From fdcacea769694663f71066de74bc3f80caee501a Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Sat, 9 Mar 2024 11:54:35 +0000 Subject: [PATCH 01/55] new arrangement Signed-off-by: LiuLingze --- .../Stack_Analyser/{libbpf => }/Makefile | 36 +- eBPF_Supermarket/Stack_Analyser/README.md | 82 +- eBPF_Supermarket/Stack_Analyser/bcc/README.md | 238 ----- .../Stack_Analyser/bcc/count_analyser.py | 59 -- .../Stack_Analyser/bcc/load_monitor.py | 241 ----- .../Stack_Analyser/bcc/mem_count.bpf.c | 129 --- eBPF_Supermarket/Stack_Analyser/bcc/my_ad.py | 129 --- .../Stack_Analyser/bcc/my_class.py | 44 - .../Stack_Analyser/bcc/my_format.py | 80 -- .../Stack_Analyser/bcc/off_cpu_count.bpf.c | 77 -- .../Stack_Analyser/bcc/on_cpu_count.bpf.c | 55 -- .../Stack_Analyser/bcc/stack_count.py | 325 ------- .../include/bpf/IOStackCollector.h | 41 + .../include/bpf/MemoryStackCollector.h | 90 ++ .../include/bpf/OffCPUStackCollector.h | 23 + .../include/bpf/OnCPUStackCollector.h | 32 + .../include/bpf/ProbeStackCollector.h | 22 + .../include/bpf/ReadaheadStackCollector.h | 32 + .../include/bpf/TemplateClass.h | 31 + .../include/bpf/eBPFStackCollector.h | 125 +++ .../{libbpf => }/include/clipp.h | 0 .../{libbpf/include/elf.h => include/elf.hpp} | 0 .../{libbpf => }/include/sa_common.h | 10 - .../{libbpf => }/include/sa_ebpf.h | 0 .../Stack_Analyser/include/sa_user.h | 54 ++ .../{libbpf => }/include/symbol.h | 0 .../{libbpf => }/include/task.h | 0 .../Stack_Analyser/libbpf/README.md | 218 ----- .../Stack_Analyser/libbpf/bpf/pre_count.bpf.c | 132 --- .../Stack_Analyser/libbpf/include/sa_user.h | 192 ---- .../Stack_Analyser/libbpf/libbpf-bootstrap | 1 - .../Stack_Analyser/libbpf/stack_analyzer.cc | 852 ------------------ ...77\347\224\250\346\226\271\346\263\225.md" | 31 - eBPF_Supermarket/Stack_Analyser/main.cpp | 200 ++++ .../src/bpf/IOStackCollector.cpp | 55 ++ .../src/bpf/MemoryStackCollector.cpp | 66 ++ .../src/bpf/OffCPUStackCollector.cpp | 33 + .../src/bpf/OnCPUStackCollector.cpp | 124 +++ .../src/bpf/ProbeStackCollector.cpp | 44 + .../src/bpf/ReadaheadStackCollector.cpp | 39 + .../Stack_Analyser/src/bpf/TemplateClass.cpp | 26 + .../src/bpf/eBPFStackCollector.cpp | 218 +++++ .../{libbpf => src}/bpf/io_count.bpf.c | 38 +- .../{libbpf => src}/bpf/mem_count.bpf.c | 0 .../{libbpf => src}/bpf/off_cpu_count.bpf.c | 0 .../{libbpf => src}/bpf/on_cpu_count.bpf.c | 0 .../Stack_Analyser/src/bpf/pre_count.bpf.c | 131 +++ .../{libbpf => src}/bpf/stack_count.bpf.c | 0 .../Stack_Analyser/src/bpf/template.bpf.c | 14 + .../{libbpf/include => src}/elf.cc | 203 +++-- .../{libbpf/include => src}/symbol.cc | 2 +- 51 files changed, 1632 insertions(+), 2942 deletions(-) rename eBPF_Supermarket/Stack_Analyser/{libbpf => }/Makefile (75%) delete mode 100644 eBPF_Supermarket/Stack_Analyser/bcc/README.md delete mode 100644 eBPF_Supermarket/Stack_Analyser/bcc/count_analyser.py delete mode 100755 eBPF_Supermarket/Stack_Analyser/bcc/load_monitor.py delete mode 100644 eBPF_Supermarket/Stack_Analyser/bcc/mem_count.bpf.c delete mode 100644 eBPF_Supermarket/Stack_Analyser/bcc/my_ad.py delete mode 100644 eBPF_Supermarket/Stack_Analyser/bcc/my_class.py delete mode 100644 eBPF_Supermarket/Stack_Analyser/bcc/my_format.py delete mode 100644 eBPF_Supermarket/Stack_Analyser/bcc/off_cpu_count.bpf.c delete mode 100644 eBPF_Supermarket/Stack_Analyser/bcc/on_cpu_count.bpf.c delete mode 100755 eBPF_Supermarket/Stack_Analyser/bcc/stack_count.py create mode 100644 eBPF_Supermarket/Stack_Analyser/include/bpf/IOStackCollector.h create mode 100644 eBPF_Supermarket/Stack_Analyser/include/bpf/MemoryStackCollector.h create mode 100644 eBPF_Supermarket/Stack_Analyser/include/bpf/OffCPUStackCollector.h create mode 100644 eBPF_Supermarket/Stack_Analyser/include/bpf/OnCPUStackCollector.h create mode 100644 eBPF_Supermarket/Stack_Analyser/include/bpf/ProbeStackCollector.h create mode 100644 eBPF_Supermarket/Stack_Analyser/include/bpf/ReadaheadStackCollector.h create mode 100644 eBPF_Supermarket/Stack_Analyser/include/bpf/TemplateClass.h create mode 100644 eBPF_Supermarket/Stack_Analyser/include/bpf/eBPFStackCollector.h rename eBPF_Supermarket/Stack_Analyser/{libbpf => }/include/clipp.h (100%) rename eBPF_Supermarket/Stack_Analyser/{libbpf/include/elf.h => include/elf.hpp} (100%) rename eBPF_Supermarket/Stack_Analyser/{libbpf => }/include/sa_common.h (89%) rename eBPF_Supermarket/Stack_Analyser/{libbpf => }/include/sa_ebpf.h (100%) create mode 100644 eBPF_Supermarket/Stack_Analyser/include/sa_user.h rename eBPF_Supermarket/Stack_Analyser/{libbpf => }/include/symbol.h (100%) rename eBPF_Supermarket/Stack_Analyser/{libbpf => }/include/task.h (100%) delete mode 100644 eBPF_Supermarket/Stack_Analyser/libbpf/README.md delete mode 100644 eBPF_Supermarket/Stack_Analyser/libbpf/bpf/pre_count.bpf.c delete mode 100644 eBPF_Supermarket/Stack_Analyser/libbpf/include/sa_user.h delete mode 160000 eBPF_Supermarket/Stack_Analyser/libbpf/libbpf-bootstrap delete mode 100644 eBPF_Supermarket/Stack_Analyser/libbpf/stack_analyzer.cc delete mode 100644 "eBPF_Supermarket/Stack_Analyser/libbpf/\346\241\206\346\236\266\344\275\277\347\224\250\346\226\271\346\263\225.md" create mode 100644 eBPF_Supermarket/Stack_Analyser/main.cpp create mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/IOStackCollector.cpp create mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/MemoryStackCollector.cpp create mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/OffCPUStackCollector.cpp create mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/OnCPUStackCollector.cpp create mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/ProbeStackCollector.cpp create mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/ReadaheadStackCollector.cpp create mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/TemplateClass.cpp create mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/eBPFStackCollector.cpp rename eBPF_Supermarket/Stack_Analyser/{libbpf => src}/bpf/io_count.bpf.c (56%) rename eBPF_Supermarket/Stack_Analyser/{libbpf => src}/bpf/mem_count.bpf.c (100%) rename eBPF_Supermarket/Stack_Analyser/{libbpf => src}/bpf/off_cpu_count.bpf.c (100%) rename eBPF_Supermarket/Stack_Analyser/{libbpf => src}/bpf/on_cpu_count.bpf.c (100%) create mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/pre_count.bpf.c rename eBPF_Supermarket/Stack_Analyser/{libbpf => src}/bpf/stack_count.bpf.c (100%) create mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/template.bpf.c rename eBPF_Supermarket/Stack_Analyser/{libbpf/include => src}/elf.cc (81%) rename eBPF_Supermarket/Stack_Analyser/{libbpf/include => src}/symbol.cc (99%) diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/Makefile b/eBPF_Supermarket/Stack_Analyser/Makefile similarity index 75% rename from eBPF_Supermarket/Stack_Analyser/libbpf/Makefile rename to eBPF_Supermarket/Stack_Analyser/Makefile index e984f7328..44a453a83 100644 --- a/eBPF_Supermarket/Stack_Analyser/libbpf/Makefile +++ b/eBPF_Supermarket/Stack_Analyser/Makefile @@ -34,12 +34,14 @@ VMLINUX := libbpf-bootstrap/vmlinux/$(ARCH)/vmlinux.h # Use our own libbpf API headers and Linux UAPI headers distributed with # libbpf to avoid dependency on system-wide headers, which could be missing or # outdated -INCLUDES := -I$(OUTPUT) -I./libbpf-bootstrap/libbpf/include/uapi -I$(dir $(VMLINUX)) -I./include +INCLUDES := -I./include -I$(OUTPUT) -I./libbpf-bootstrap/libbpf/include/uapi -I$(dir $(VMLINUX)) CFLAGS := -g -Wall ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS) -APPS = on_cpu_count off_cpu_count mem_count io_count pre_count stack_count -SYMBOL = elf symbol +BPF = $(patsubst src/bpf/%.bpf.c, %, ${wildcard src/bpf/*.bpf.c}) +BPF_WAPPER = $(patsubst src/bpf/%.cpp, %, ${wildcard src/bpf/*.cpp}) +THIRD_PARTY = $(patsubst src/%.cc, %, ${wildcard src/*.cc}) + TARGETS = stack_analyzer # Get Clang's default includes on this system. We'll explicitly add these dirs @@ -73,17 +75,18 @@ endef $(call allow-override,CC,$(CROSS_COMPILE)cc) $(call allow-override,LD,$(CROSS_COMPILE)ld) +args = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}` .PHONY: all all: $(TARGETS) .PHONY: bpf_skel_h -bpf_skel_h: $(APPS) +bpf_skel_h: $(BPF) .PHONY: clean clean: $(call msg,CLEAN) - $(Q)rm -rf $(OUTPUT) $(TARGETS) bpf/*.skel.h + $(Q)rm -rf $(OUTPUT) $(TARGETS) include/bpf/*.skel.h $(OUTPUT) $(OUTPUT)/libbpf $(BPFTOOL_OUTPUT): $(call msg,MKDIR,$@) @@ -103,7 +106,7 @@ $(BPFTOOL): | $(BPFTOOL_OUTPUT) $(Q)$(MAKE) ARCH= CROSS_COMPILE= OUTPUT=$(BPFTOOL_OUTPUT)/ -C $(BPFTOOL_SRC) bootstrap # Build BPF code -$(OUTPUT)/%.bpf.o: bpf/%.bpf.c $(LIBBPF_OBJ) $(wildcard %.h) $(VMLINUX) | $(OUTPUT) $(BPFTOOL) +$(OUTPUT)/%.bpf.o: src/bpf/%.bpf.c $(LIBBPF_OBJ) $(wildcard %.h) $(VMLINUX) | $(OUTPUT) $(BPFTOOL) $(call msg,BPF,$@) $(Q)$(CLANG) -g -O2 -target bpf -D__TARGET_ARCH_$(ARCH) \ $(INCLUDES) $(CLANG_BPF_SYS_INCLUDES) \ @@ -111,22 +114,27 @@ $(OUTPUT)/%.bpf.o: bpf/%.bpf.c $(LIBBPF_OBJ) $(wildcard %.h) $(VMLINUX) | $(OUTP $(Q)$(BPFTOOL) gen object $@ $(patsubst %.bpf.o,%.tmp.bpf.o,$@) # Generate BPF skeletons -.PHONY: $(APPS) -$(APPS): %: $(OUTPUT)/%.bpf.o | $(OUTPUT) $(BPFTOOL) +.PHONY: $(BPF) +$(BPF): %: $(OUTPUT)/%.bpf.o | $(OUTPUT) $(BPFTOOL) $(call msg,GEN-SKEL,$@) - $(Q)$(BPFTOOL) gen skeleton $< > bpf/$@.skel.h + $(Q)$(BPFTOOL) gen skeleton $< > include/bpf/$@.skel.h + +$(patsubst %,$(OUTPUT)/%.o,$(BPF_WAPPER)): $(OUTPUT)/%.o: src/bpf/%.cpp + $(call msg,CXX,$@) + $(Q)$(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $@ # Build depending library -$(patsubst %,$(OUTPUT)/%.o,$(SYMBOL)): $(OUTPUT)/%.o: include/%.cc +$(patsubst %,$(OUTPUT)/%.o,$(THIRD_PARTY)): $(OUTPUT)/%.o: src/%.cc $(call msg,CXX,$@) - $(Q)$(CXX) $(CFLAGS) -c $< -o $@ + $(Q)$(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $@ +# $(Q)$(CXX) $(CFLAGS) $(INCLUDES) $< -E > log -$(OUTPUT)/$(TARGETS).o: $(TARGETS).cc $(APPS) | $(OUTPUT) +$(OUTPUT)/$(TARGETS).o: main.cpp $(BPF) $(patsubst %,$(OUTPUT)/%.o,$(BPF_WAPPER)) | $(OUTPUT) $(call msg,CXX,$@) - $(Q)$(CXX) $(CFLAGS) $(INCLUDES) -c $(filter %.cc,$^) -o $@ + $(Q)$(CXX) $(CFLAGS) $(INCLUDES) -c main.cpp -o $@ # Build application binary -$(TARGETS): %: $(OUTPUT)/%.o $(patsubst %,$(OUTPUT)/%.o,$(SYMBOL)) $(LIBBPF_OBJ) | $(OUTPUT) +$(TARGETS): %: $(OUTPUT)/%.o $(patsubst %,$(OUTPUT)/%.o,$(THIRD_PARTY)) $(patsubst %,$(OUTPUT)/%.o,$(BPF_WAPPER)) $(LIBBPF_OBJ) | $(OUTPUT) $(call msg,BINARY,$@) $(Q)$(CXX) $^ $(ALL_LDFLAGS) -lstdc++ -lelf -lz -o $@ diff --git a/eBPF_Supermarket/Stack_Analyser/README.md b/eBPF_Supermarket/Stack_Analyser/README.md index 5b19ea51d..37e2033f5 100644 --- a/eBPF_Supermarket/Stack_Analyser/README.md +++ b/eBPF_Supermarket/Stack_Analyser/README.md @@ -1,8 +1,10 @@ -# 1. 功能描述 +# 功能描述 对操作系统各方面的调用栈进行计数,从中分析程序性能瓶颈。 -## 2.1 应用场景及意义 +# 意义 + +## 应用场景及意义 Stack_Analyzer是一个基于eBPF的按照指定时间间隔(默认为5s)来统计涉及特定子系统的进程函数调用栈的性能指标的工具。使用它可以帮助您便捷地查看相关子系统性能损耗最高或者对系统吞吐量影响较大的瓶颈调用栈,直接而具体地设计并进行程序或系统性能上的优化,进而降低对cpu性能的损耗,提高系统吞吐量,以增强车机系统的实时性。 @@ -16,7 +18,7 @@ Stack_Analyzer是一个基于eBPF的按照指定时间间隔(默认为5s)来 除此之外,本项目设计了一个便于复用的调用栈采集框架,方便监测指标的添加。之后可根据需求添加更多的监测指标。 -## 2.2 性能参数及观测意义 +## 性能参数及观测意义 采集的指标对主要子系统进行了覆盖,分为以下五个部分: @@ -28,9 +30,9 @@ Stack_Analyzer是一个基于eBPF的按照指定时间间隔(默认为5s)来 为了易于分析调用栈数据,项目加入更多的可视化元素和交互方式,使得画像更加直观、易于理解,对优化程序或系统性能有重要意义。 -# 2. 要求 +# 使用要求 -## 2.1 内核要求 +## 内核配置要求 - 版本:>= Linux 5.10 - 开启内核选项: @@ -53,25 +55,61 @@ Stack_Analyzer是一个基于eBPF的按照指定时间间隔(默认为5s)来 - CONFIG_DEBUG_INFO_BTF=y - CONFIG_FTRACE_SYSCALLS=y -## 2.2 数据准确性要求 +## 数据准确性要求 添加 `-g -fno-omit-frame-pointer` 选项编译被测程序以保留程序的fp信息,以便监测程序可以通过fp信息回溯被测程序的调用栈。 -# 4. 目录描述 +## 编译要求 + +Ubuntu下需要安装一下依赖,其他发行版类似 + +```shell +$ git submodule update --init --recursive +$ apt install clang libelf1 libelf-dev zlib1g-dev +``` + +g++-10以上 +clang-12以上 + +# 使用方法 + +## 工具编译 + +```shell +$ make +``` + +## 命令使用方法 + +```shell +$ ./stack_analyzer -h +``` + +## 输出格式 + +```shell +Type:OnCPUTime Unit:nanoseconds Period:20408163 +time:20240309_06_23_32 +counts: +pid usid ksid count +23640 126625 88396 1 +traces: +sid trace +88396 entry_SYSCALL_64_after_hwframe;do_syscall_64;__x64_sys_clone;__do_sys_clone;kernel_clone;copy_process;dup_mm.constprop.0;dup_mmap;copy_page_range;copy_p4d_range;copy_pte_range;__pte_alloc;pte_alloc_one;alloc_pages;__alloc_pages;get_page_from_freelist;clear_page_orig; +126625 _Fork+0x7ff997200027; +groups: +pid tgid +23640 23640 +commands: +23640 node +OK +``` + +# 目录描述 -- libbpf:使用libbpf框架开发的调用栈数据采集程序,性能较高,可扩展性强 +- include:各种定义。 +- include/bpf:eBPF程序的骨架头文件和其包装类的定义。 +- src:各种实现。 +- src/bpf:eBPF程序的代码和其包装类的实现。 - exporter:使用Golang开发的数据推送程序,将采集到的调用栈数据推送到Pyroscope服务器,获取更强的数据存储和可视化性能。 -- bcc:使用bcc框架开发的调用栈数据采集程序,适配性和数据分析能力较强,目前正在开发中。 - -# 3. 计划安排 - -- [x] 实时输出功能 -- [x] on-cpu 栈采集功能 -- [x] off-cpu 栈采集功能 -- [x] malloc-free 栈采集功能 -- [x] 保存为json文件功能 -- [x] 火焰图绘制功能 -- [x] io-write栈采集功能 -- [x] 加入排序功能 -- [x] 收发包栈采集功能 -- [ ] 栈数据智能分析功能 \ No newline at end of file +- main.cpp:负责参数解析、配置、调用栈数据收集器管理和子进程管理。 \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/bcc/README.md b/eBPF_Supermarket/Stack_Analyser/bcc/README.md deleted file mode 100644 index 9b919e0fa..000000000 --- a/eBPF_Supermarket/Stack_Analyser/bcc/README.md +++ /dev/null @@ -1,238 +0,0 @@ -# 运行方法 - -消耗较大,但功能较强,结合机器学习pca算法进行栈分析 - -## 安装依赖 - -```shell -python -m pip install --upgrade pip -sudo python -m pip install pyod -sudo python -m pip install psutil -sudo apt-get install -y linux-headers-$(uname -r) -sudo apt-get install -y python-is-python3 -sudo apt-get install -y bison build-essential cmake flex git libedit-dev libllvm11 llvm-11-dev libclang-11-dev zlib1g-dev libelf-dev libfl-dev python3-distutils -sudo ln -s /usr/lib/llvm-11 /usr/local/llvm -``` - -## 编译依赖 - -```shell -cd bcc -wget https://github.com/iovisor/bcc/releases/download/v0.25.0/bcc-src-with-submodule.tar.gz -tar xf bcc-src-with-submodule.tar.gz -cd bcc/ -mkdir build -cd build/ -cmake -DCMAKE_INSTALL_PREFIX=/usr -DPYTHON_CMD=python3 .. -make -sudo make install -cd ../../ -``` - -## 运行 - -stack_analyzer - -```shell -usage: stack_count.py [-h] [-p PID | -t TID | -c Command | -u | -k] [-U | -K] [-a] [-d] [-f] [-s] [-m MODE] [--stack-storage-size STACK_STORAGE_SIZE] - [--state STATE] - [duration] - -Summarize on-CPU time by stack trace - -positional arguments: - duration duration of trace, in seconds - -options: - -h, --help show this help message and exit - -p PID, --pid PID trace this PID only - -t TID, --tid TID trace this TID only - -c Command, --cmd Command - trace this command only - -u, --user-threads-only - user threads only (no kernel threads) - -k, --kernel-threads-only - kernel threads only (no user threads) - -U, --user-stacks-only - show stacks from user space only (no kernel space stacks) - -K, --kernel-stacks-only - show stacks from kernel space only (no user space stacks) - -a, --auto analyzing stacks automatically - -d, --delimited insert delimiter between kernel/user stacks - -f, --folded output folded format - -s, --offset show address offsets - -m MODE, --mode MODE mode of stack counting, 'on_cpu'/'off_cpu'/'mem' - --stack-storage-size STACK_STORAGE_SIZE - the number of unique stack traces that can be stored and displayed (default 16384) - --state STATE filter on this thread state bitmask (eg, 2 == TASK_UNINTERRUPTIBLE) see include/linux/sched.h - -examples: - sudo -E ./stack_count.py # trace on-CPU stack time until Ctrl-C - sudo -E ./stack_count.py -m off_cpu # trace off-CPU stack time until Ctrl-C - sudo -E ./stack_count.py 5 # trace for 5 seconds only - sudo -E ./stack_count.py -f 5 # 5 seconds, and output as stack_count.svg in flame graph format - sudo -E ./stack_count.py -s 5 # 5 seconds, and show symbol offsets - sudo -E ./stack_count.py -p 185 # only trace threads for PID 185 - sudo -E ./stack_count.py -t 188 # only trace thread 188 - sudo -E ./stack_count.py -c cmdline # only trace threads of cmdline - sudo -E ./stack_count.py -u # only trace user threads (no kernel) - sudo -E ./stack_count.py -k # only trace kernel threads (no user) - sudo -E ./stack_count.py -U # only show user space stacks (no kernel) - sudo -E ./stack_count.py -K # only show kernel space stacks (no user) - sudo -E ./stack_count.py -a # anomaly detection for stack -``` - -load_monitor,计划将该工具以阈值控制选项的形式与stack_analyzer合并 - -```shell -usage: load_monitor.py [-h] [-t TIME] [-F FREQ] [-d DELAY] [-l THRESHOLD] [-r] - -Summarize on-CPU time by stack trace - -options: - -h, --help show this help message and exit - -t TIME, --time TIME running time - -F FREQ, --frequency FREQ - monitor frequency - -d DELAY, --delay DELAY - output delay(interval) - -l THRESHOLD, --threshold THRESHOLD - load limit threshold - -r, --report - -examples: - ./load_monitor.py # monitor system load until Ctrl-C - ./load_monitor.py -t 5 # monitor for 5 seconds only -``` - -# 运行效果 - -展示工具的输出格式及说明 - -## 实时输出测试结果 - -```shell -Stack_Analyser/libbpf$ sudo ./stack_analyzer -p 12532 ----------7--------- -12532 ( 38758,118464) 1 -12532 ( 77616, 97063) 1 -12532 ( -14,116464) 1 -12532 ( -14, 18600) 1 -12532 ( 31291, 87833) 1 ----------5--------- ----------7--------- -12532 ( -1, 91718) 3482309 -12532 ( -1, 38038) 3533633 -12532 ( -1, 89746) 377229951 -12532 ( -1, 83783) 2977594 -``` - -代码示为on-cpu、off-cpu和内存栈数据分别采集stress-ng-malloc 5s的输出,由分割线分开,分割线中间的数字为map fd,分割线间,第一列为pid,第二列括号中用户栈id和内核栈id,第三列为栈的数量,计数单位略有不同,on-cpu计数单位为次,off-cpu计数单位为0.1ms,内存计数单位为1kB - -## json文件结果 - -```json -{ - "12532": { - "12532": { - "stacks": { - "91718,-1": { - "count": 3482309, - "trace": [ - "MISSING KERNEL STACK", - "stress_malloc_loop" - ] - } - }, - "name": "stress-ng-mallo" - } - } -} -``` - -以上代码为保存的json文件片段展开后的内容,是一个跟踪stress-ng-malloc采集到的内存栈信息,其内核栈标注为"MISSING KERNEL STACK",表示内核栈没有被采集。 - -## bcc/load_monitor.py - -用于在计算机负载超过阈值时记录内核栈数量信息,每5s输出一次总记录。 - -终止时将记录以 栈-数量 的格式保存在 `./stack.bpf` 中,并输出火焰图文件 `./stack.svg` - -## 输出片段 - -屏幕输出: -```log -____________________________________________________________ -0xffffffff928fced1 update_rq_clock -0xffffffff92904c34 do_task_dead -0xffffffff928c40a1 do_exit -0xffffffff928c421b do_group_exit -0xffffffff928d5280 get_signal -0xffffffff9283d6ce arch_do_signal_or_restart -0xffffffff9296bcc4 exit_to_user_mode_loop -0xffffffff9296be00 exit_to_user_mode_prepare -0xffffffff9359db97 syscall_exit_to_user_mode -0xffffffff93599809 do_syscall_64 -0xffffffff93600099 entry_SYSCALL_64_after_hwframe -stackid count pid comm -5 37 - 82731 5 - 82783 IPC I/O Parent - 82794 TaskCon~ller #1 - 82804 pool-spawner - 82830 Breakpad Server - 82858 Socket Thread - 82859 JS Watchdog - 82860 Backgro~Pool #1 - 82861 Timer - 82862 RemVidChild - 82863 ImageIO - 82864 Worker Launcher - 82865 TaskCon~ller #0 - 82867 ImageBridgeChld - 82869 ProfilerChild - 82870 AudioIP~ack RPC - 82871 AudioIP~ver RPC - 82877 dconf worker - 82885 snap - 83010 StreamTrans #1 - 83011 StreamTrans #2 - 83018 StreamTrans #3 - 83020 StreamTrans #5 - 83029 JS Watchdog - 83030 Backgro~Pool #1 - 83031 Timer - 83033 ImageIO - 83034 Worker Launcher - 83036 TaskCon~ller #1 - 83037 ImageBridgeChld - 83048 IPC I/O Child - 83049 Socket Thread - 83051 Backgro~Pool #1 - 83052 Timer - 83053 RemVidChild - 83055 TaskCon~ller #0 - 83059 ProfilerChild -____________________________________________________________ -``` - -文件输出: -```log -@[ -update_rq_clock -sched_autogroup_exit_task -do_exit -do_group_exit -get_signal -arch_do_signal_or_restart -exit_to_user_mode_loop -exit_to_user_mode_prepare -syscall_exit_to_user_mode -do_syscall_64 -entry_SYSCALL_64_after_hwframe -]: 37 -``` - -## 火焰图文件结果 - -
stack.svg
\ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/bcc/count_analyser.py b/eBPF_Supermarket/Stack_Analyser/bcc/count_analyser.py deleted file mode 100644 index 9085eef8d..000000000 --- a/eBPF_Supermarket/Stack_Analyser/bcc/count_analyser.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/python - -''' -Copyright 2023 The LMP Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -author: luiyanbing@foxmail.com - -数据直方图分析脚本 -''' - -import matplotlib.pyplot as plt -from time import time - -data = [] -with open('stack_count.stk', 'r') as f: - for line in f: - line = line.replace('\n','') - if line.isdigit(): - data.append([int(line)]) - -from pyod.models.mad import MAD -from pyod.models.pca import PCA -from pyod.models.knn import KNN -from pyod.models.iforest import IForest -clfs = [MAD(), PCA(), KNN(), IForest()] -# clfs = [ECOD()] -for clf in clfs: - start = time() - clf.fit(data) - end = time() - print(clf.__module__, end-start) - labels = clf.labels_.astype(int).tolist() - count = [[],[]] - for c, l in zip(data, labels): - if l: - count[1].append(c[0]) - else: - count[0].append(c[0]) - plt.figure(figsize=(6,4)) - plt.hist(count, bins=100, label=['normal', 'anomaly'], color=['c','r']) - plt.ylim([0,10]) - plt.xlabel('Stack Count', fontdict={'family' : 'DejaVu Serif'}) - plt.ylabel('Frequency', fontdict={'family' : 'DejaVu Serif'}) - plt.legend(prop={'family' : 'DejaVu Serif'}) - plt.title(clf.__module__, fontdict={'family' : 'DejaVu Serif'}) - plt.savefig('on-cpu-%s.png'%(clf.__module__)) - plt.close() \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/bcc/load_monitor.py b/eBPF_Supermarket/Stack_Analyser/bcc/load_monitor.py deleted file mode 100755 index 01ca9d35f..000000000 --- a/eBPF_Supermarket/Stack_Analyser/bcc/load_monitor.py +++ /dev/null @@ -1,241 +0,0 @@ -#!/bin/python3 - -''' -Copyright 2023 The LMP Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -author: luiyanbing@foxmail.com - -高负载进程调用栈监控脚本 -''' - -from time import time, sleep, strftime -from signal import signal, SIG_IGN - - -def nice_1(): - from os import nice - nice(-20) - -nice_1() - -mem_path = "/dev/shm/load_monitor_tex.pkl" - -def get_args(): - from argparse import ArgumentParser, ArgumentTypeError, RawDescriptionHelpFormatter - # arguments - examples = """examples: - ./load_monitor.py # monitor system load until Ctrl-C - ./load_monitor.py -t 5 # monitor for 5 seconds only - """ - - def positive_int(val): - try: - ival = int(val) - except ValueError: - raise ArgumentTypeError("must be an integer") - if ival <= 0: - raise ArgumentTypeError("must be positive") - return ival - - - parser = ArgumentParser( - description="Summarize on-CPU time by stack trace", - formatter_class=RawDescriptionHelpFormatter, - epilog=examples) - parser.add_argument("-t", "--time", default=99999999, dest="time", - type=positive_int, help="running time") - parser.add_argument("-F", "--frequency", default=99, dest="freq", - type=positive_int, help="monitor frequency") - parser.add_argument("-d", "--delay", default=10, dest="delay", - type=positive_int, help="output delay(interval)") - parser.add_argument("-l", "--threshold", default=8, dest="threshold", - type=positive_int, help="load limit threshold") - # parser.add_argument("-f", "--flame-graph", action='store_true', dest="flame") - parser.add_argument("-r", "--report", action='store_true', dest="report") - return parser.parse_args() - -args = get_args() - -if args.report: - with open(mem_path, "r") as file: - print(file.read()) - from os import remove - remove(mem_path) - exit() - -code = """ -#include -#define LOAD_LIMIT LOAD_LIMIT_THRESHOLD -#define MAX_ENTITY 10240 -#define avenrun AVENRUN_ADDRULL -typedef struct { - int pid, usid, ksid, o; - char comm[TASK_COMM_LEN]; -} TaskData; -BPF_STACK_TRACE(stack_trace, MAX_ENTITY); -BPF_HASH(stack_count, TaskData, u32, MAX_ENTITY); -BPF_ARRAY(load, unsigned long, 1); -void do_stack(struct pt_regs *ctx) { - unsigned long avg_load; - bpf_probe_read_kernel(&avg_load, sizeof(avg_load), (void *)avenrun); - avg_load >>= 11; - int zero = 0; - load.update(&zero, &avg_load); - if(avg_load >= LOAD_LIMIT) { - struct task_struct *task = (struct task_struct *)bpf_get_current_task(); - - TaskData td = { - .pid = bpf_get_current_pid_tgid() >> 32, - .ksid = stack_trace.get_stackid(ctx, BPF_F_FAST_STACK_CMP), - .usid = stack_trace.get_stackid(ctx, BPF_F_USER_STACK | BPF_F_FAST_STACK_CMP), - .o = 0, - }; - bpf_get_current_comm(td.comm, TASK_COMM_LEN); - stack_count.increment(td); - } -} -""" - -def get_load(code): - from subprocess import Popen, PIPE - p = Popen("sudo cat /proc/kallsyms | grep ' avenrun'", shell=True, stdout=PIPE) - p.wait() - evanrun_addr = "0x" + p.stdout.read().split()[0].decode() - # print("get addr of evanrun: ", evanrun_addr) - return code.replace("AVENRUN_ADDR", evanrun_addr) - -code = get_load(code) -code = code.replace("LOAD_LIMIT_THRESHOLD", str(args.threshold)) -# !!!segfault -# import ctypes -# addr = int(evanrun_addr, base=16) -# load = ctypes.cast(addr, ctypes.POINTER(ctypes.c_ulong)).contents - -def attach_bpf(): - from bcc import BPF, PerfType, PerfSWConfig - bpf = BPF(text=code) - bpf.attach_perf_event(ev_type=PerfType.SOFTWARE, - ev_config=PerfSWConfig.CPU_CLOCK, fn_name="do_stack", - sample_period=0, sample_freq=args.freq) - return bpf - -bpf = attach_bpf() - -def detach_bpf(bpf): - from bcc import BPF, PerfType, PerfSWConfig - bpf.detach_perf_event(ev_type=PerfType.SOFTWARE, - ev_config=PerfSWConfig.CPU_CLOCK) - -def format_tex(): - stackcount = {TaskData(k): v.value for k, - v in bpf["stack_count"].items()} - bpf["stack_count"].clear() - stackcount = sorted(stackcount.items(), - key=lambda d: d[1], reverse=False) - timestr = strftime("%H:%M:%S") - tex = '' - for d in stackcount: - tex += "_"*32+'\n' - tex += "%-5d:%16s %d\n" % (d[0].pid, d[0].comm, d[1]) - if d[0].ksid >= 0: - for j in bpf["stack_trace"].walk(d[0].ksid): - tex += "\t%#08x %s\n" % (j, bpf.ksym(j).decode()) - else: - tex += "\t[MKS]\n" - tex += "\t"+"-"*16 + '\n' - if d[0].usid >= 0: - for j in bpf["stack_trace"].walk(d[0].usid): - tex += "\t%#08x %s\n" % (j, bpf.sym(j, d[0].pid).decode()) - else: - tex += "\t[MUS]\n" - tex += "_"*26 + timestr + "_"*26 + '\n' - return tex - -def fla_tex(): - stackcount = {TaskData(k): v.value for k, - v in bpf["stack_count"].items()} - bpf["stack_count"].clear() - max_deep = 0 - for k in stackcount.keys(): - if (k.usid >= 0): - deep = 0 - for _ in bpf["stack_trace"].walk(k.usid): - deep += 1 - if max_deep < deep: - max_deep = deep - tex = '' - for k, v in stackcount.items(): - line = '' - if (k.ksid >= 0): - for i in bpf["stack_trace"].walk(k.ksid): - line = bpf.ksym(i).decode()+';' + line - else: - line = "[MKS];" + line - line = "-"*16+';' + line - deep = 0 - if (k.usid >= 0): - for i in bpf["stack_trace"].walk(k.usid): - line = bpf.sym(i, k.pid).decode()+";" + line - deep += 1 - else: - line = "[MUS];" + line - deep = 1 - line = '.;'*(max_deep - deep) + line - line = '%s:%d;' % (k.comm, k.pid) + line - line += " %d\n" % v - tex += line - return tex - -class TaskData: - def __init__(self, a) -> None: - self.pid = a.pid - self.ksid = a.ksid - self.usid = a.usid - self.comm = a.comm.decode() - -mem_file = open(mem_path, "a") - -def sig_handle(*_): - print("\b\bQuit...\n") - detach_bpf(bpf) - # tex = format_tex() - # print(tex, file=mem_file) - mem_file.close() - exit() - -signal(2, sig_handle) -signal(1, sig_handle) -start = 0. -load = bpf["load"] -period = 1/(args.freq + 1) -print("start...") - -for _ in range(args.time): - load_5 = int(load[0].value) - # print(load_5, end=' ') - if (load_5 < args.threshold): - sleep(period) - elif (time()-start > args.delay): - # print(".") - sleep(period*100) - tex = format_tex() - print(tex, file=mem_file) - start = time() - else: - sleep(args.delay) - -signal(2, SIG_IGN) -signal(1, SIG_IGN) -sig_handle() \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/bcc/mem_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/bcc/mem_count.bpf.c deleted file mode 100644 index 56fc444ab..000000000 --- a/eBPF_Supermarket/Stack_Analyser/bcc/mem_count.bpf.c +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2023 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 内核态ebpf的内存模块代码 -#include - -typedef struct { - u32 pid; - int32_t ksid, usid; -} psid; - -typedef struct { - char str[TASK_COMM_LEN]; -} comm; - -BPF_HASH(psid_count, psid, u64); -BPF_STACK_TRACE(stack_trace, STACK_STORAGE_SIZE); -BPF_HASH(pid_tgid, u32, u32); -BPF_HASH(pid_comm, u32, comm); - -typedef struct -{ - __u64 addr; - __u32 pid, o; -} piddr; // mem info key - -typedef struct -{ - __u64 size; - __u32 usid, o; -} mem_info; // mem info with stack - -BPF_HASH(pid_size, u32, u64); -BPF_HASH(piddr_meminfo, piddr, mem_info); - -int malloc_enter(struct pt_regs *ctx) -{ - u64 size = PT_REGS_PARM1(ctx) >> 10; - if(!size) return -1; - // record data - u64 pt = bpf_get_current_pid_tgid(); - u32 pid = pt >> 32; - u32 tgid = pt; - pid_tgid.update(&pid, &tgid); - comm *p = pid_comm.lookup(&pid); - if (!p) - { - comm name; - bpf_get_current_comm(&name, TASK_COMM_LEN); - pid_comm.update(&pid, &name); - } - - // record size - return pid_size.update(&pid, &size); -} - -int malloc_exit(struct pt_regs *ctx) -{ - // get size - u32 pid = bpf_get_current_pid_tgid() >> 32; - u64 *size = pid_size.lookup(&pid); - if(!size) return -1; - - // record stack count - psid apsid = { - .pid = pid, - .usid = USER_STACK_GET, - .ksid = -1, - }; - u64 *count = psid_count.lookup(&apsid); - if (!count) - psid_count.update(&apsid, size); - else (*count) += *size; - - // record pid_addr-info - u64 addr = PT_REGS_RC(ctx); - piddr a = { - .addr = addr, - .pid = pid, - .o = 0, - }; - mem_info info = { - .size = *size, - .usid = apsid.usid, - .o = 0, - }; - piddr_meminfo.update(&a, &info); - - // delete pid-size - return pid_size.delete(&pid); -} - -int free_enter(struct pt_regs *ctx) -{ - u64 addr = PT_REGS_PARM1(ctx); - // get freeing size - u32 pid = bpf_get_current_pid_tgid() >> 32; - piddr a = {addr, pid}; - mem_info *info = piddr_meminfo.lookup(&a); - if(!info) return -1; - - // get allocated size - psid apsid = { - .ksid = -1, - .pid = pid, - .usid = info->usid, - }; - u64 *size = psid_count.lookup(&apsid); - if(!size) return -1; - - // sub the freeing size - (*size) -= info->size; - - // del freeing addr info - return piddr_meminfo.delete(&a); -} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/bcc/my_ad.py b/eBPF_Supermarket/Stack_Analyser/bcc/my_ad.py deleted file mode 100644 index 44505203f..000000000 --- a/eBPF_Supermarket/Stack_Analyser/bcc/my_ad.py +++ /dev/null @@ -1,129 +0,0 @@ -''' -Copyright 2023 The LMP Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -author: luiyanbing@foxmail.com - -异常检测相关函数 -''' - -from my_class import psid_t -from pyod.models.base import BaseDetector -from pyod.models.pca import PCA -from time import time - - -class adc: - - clf:BaseDetector - mutant:dict - res_prev:dict - mutant_avg:float - - def __init__(self, clf=PCA()) -> None: - self.clf = clf - self.mutant = dict() - self.res_prev = None - self.mutant_avg = 0 - - def do_label(self, count) -> list: - start = time() - self.clf.fit(count) - print(self.clf.__module__, time() - start) - return self.clf.labels_ - - def auto_label(self, b) -> None: - psids = [psid_t(psid) for psid in b["psid_count"].keys()] - counts = [[i.value] for i in b["psid_count"].values()] - labels = self.do_label(counts) - self.mutant = {psid: label for psid, label in zip( - psids, labels, strict=True)} - - def ad_log(self, b) -> None: - mutant = self.mutant - res_prev = self.res_prev - psid_count = {psid_t(psid): n.value for psid, - n in b["psid_count"].items()} - count = [[n] for n in psid_count.values()] - try: - labels = self.do_label(count) - except: - return - res = { - psid: label for psid, label - in zip(psid_count.keys(), labels, strict=True) - } - for (psid, label), c in zip(res.items(), count): - # if psid.ksid < 0 and psid.usid < 0: - # continue - - # f = False - # n = mutant.setdefault(psid, 0) - # if res_prev and psid in res_prev.keys(): - # if label > res_prev[psid]: - # f = True - # mutant[psid] = n+1 - # else: - # mutant[psid] = n-1 - # elif label: - # f = True - # n = mutant.setdefault(psid, 0) - # mutant[psid] = n+1 - # if f: - # print('pid:%6d\tsid:(%6d,%6d)\tcount:%-6d' % - # (psid.pid, psid.ksid, psid.usid, c[0])) - - if label: - print('pid:%6d\tsid:(%6d,%6d)\tcount:%-6d' % - (psid.pid, psid.ksid, psid.usid, c[0])) - - self.res_prev = res - print('-'*32) - - def avg_mutant(self) -> None: - ad_n = self.mutant.values() - if len(ad_n): - self.mutant_avg = sum(ad_n)/len(ad_n) - else: - self.mutant_avg = 0 - # for k, v in self.mutant.items(): - # print(k, v) - # print(ad_avg) - - def get_mutant(self, psid) -> int: - if psid in self.mutant.keys(): - return 1 if self.mutant[psid] > self.mutant_avg else -1 - else: - return 0 - -def rate(tgids: dict, rate_comm: callable): - tp = fp = p = 0 - for tgd in tgids.values(): - for pd in tgd.values(): - if rate_comm(pd['name']): - p += 1 - f = False - for sd in pd['stacks'].values(): - if sd['label'] == 1: - print(pd['name']) - if rate_comm(pd['name']): - tp += 1 - else: - fp += 1 - f = True - break - if f: - break - print("recall:%f%% precision:%f%%" % - (tp/p*100 if p else 0, tp/(tp+fp)*100 if tp+fp else 0)) diff --git a/eBPF_Supermarket/Stack_Analyser/bcc/my_class.py b/eBPF_Supermarket/Stack_Analyser/bcc/my_class.py deleted file mode 100644 index 8d853b5e9..000000000 --- a/eBPF_Supermarket/Stack_Analyser/bcc/my_class.py +++ /dev/null @@ -1,44 +0,0 @@ -''' -Copyright 2023 The LMP Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -author: luiyanbing@foxmail.com - -数据对象定义 -''' - -from json import dumps, JSONEncoder - -class psid_t: - def __init__(self, psid) -> None: - self.pid = psid.pid - self.ksid = psid.ksid - self.usid = psid.usid - - def __hash__(self) -> int: - return hash(str(self.pid)+str(self.ksid)+str(self.usid)) - - def __eq__(self, other) -> bool: - return self.pid == other.pid and self.ksid == other.ksid and self.usid == other.usid - - def __str__(self) -> str: - return ' '.join([str(self.pid), str(self.ksid), str(self.usid)]) - - -class MyEncoder(JSONEncoder): - def default(self, obj): - if isinstance(obj, int): - return obj.value - else: - return super(MyEncoder, self).default(obj) diff --git a/eBPF_Supermarket/Stack_Analyser/bcc/my_format.py b/eBPF_Supermarket/Stack_Analyser/bcc/my_format.py deleted file mode 100644 index b742fcde5..000000000 --- a/eBPF_Supermarket/Stack_Analyser/bcc/my_format.py +++ /dev/null @@ -1,80 +0,0 @@ -''' -Copyright 2023 The LMP Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -author: luiyanbing@foxmail.com - -数据格式化相关的函数 -''' - -from my_class import * - -def map2dict(b, get_mutant: callable, need_delimiter=True, show_offset=False) -> dict: - psid_count = {psid_t(psid): count.value for psid, - count in b["psid_count"].items()} - pid_comm = {pid.value: comm.str.decode() - for pid, comm in b["pid_comm"].items()} - pid_tgid = {pid.value: tgid.value for pid, tgid in b["pid_tgid"].items()} - stack_trace = b["stack_trace"] - - tgids = dict() - for pid, tgid in pid_tgid.items(): - tgid_d = tgids.setdefault(tgid, dict()) - tgid_d[pid] = {'name': pid_comm[pid]} - - for psid, n in psid_count.items(): - stks_d = tgids[pid_tgid[psid.pid] - ][psid.pid].setdefault('stacks', dict()) - stks_d[str(psid.ksid)+','+str(psid.usid)] = { - 'trace': ( - (["%#016x:%s" % (j, b.ksym(j).decode()) - for j in stack_trace.walk(psid.ksid)] if psid.ksid >= 0 else ['[Missed Kernel Stack]']) + - (['-'*50] if need_delimiter else []) + - (["%#016x:" % (j) - for j in stack_trace.walk(psid.usid)] if psid.usid >= 0 else ['[Missed User Stack]']) - ), 'count': n, 'label': get_mutant(psid) - } - return tgids - - -def fla_text(b, need_delimiter): - psid_count = {psid_t(psid): count.value for psid, - count in b["psid_count"].items()} - stack_trace = b["stack_trace"] - - def get_deep(stack_trace, usid): - if (usid < 0): - return 0 - deep = 0 - for _ in stack_trace.walk(usid): - deep += 1 - return deep - - deeps = [get_deep(stack_trace, psid.usid) for psid in psid_count.keys()] - max_deep = 0 - for deep in deeps: - if max_deep < deep: - max_deep = deep - lines = '' - for (psid, count), deep in zip(psid_count.items(), deeps, strict=True): - lines += ''.join( - (["%s\n" % (b.ksym(j).decode()) - for j in stack_trace.walk(psid.ksid)] if psid.ksid >= 0 else []) + - (['-'*32+'\n'] if need_delimiter else []) + - (["%s\n" % (b.sym(j, psid.pid, show_module=True).decode()) - for j in stack_trace.walk(psid.usid)] if psid.usid >= 0 else []) + - ['.\n'*(max_deep - deep)] + - [str(count) + '\n'*2] - ) - print(lines) \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/bcc/off_cpu_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/bcc/off_cpu_count.bpf.c deleted file mode 100644 index 04ed7a4d3..000000000 --- a/eBPF_Supermarket/Stack_Analyser/bcc/off_cpu_count.bpf.c +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2023 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 内核态ebpf的阻塞模块代码 -#include -#include - -#define MINBLOCK_US 1ULL -#define MAXBLOCK_US 99999999ULL - -typedef struct { - u32 pid; - int usid; - int ksid; -} psid; - -typedef struct { - char str[TASK_COMM_LEN]; -} comm; - -BPF_HASH(psid_count, psid); -BPF_HASH(start, u32); -BPF_STACK_TRACE(stack_trace, STACK_STORAGE_SIZE); -BPF_HASH(pid_tgid, u32, u32); -BPF_HASH(pid_comm, u32, comm); - -int do_stack(struct pt_regs *ctx, struct task_struct *curr) { - u32 pid = curr->pid; - u32 tgid = curr->tgid; - - if ((THREAD_FILTER) && (STATE_FILTER)) { - u64 ts = bpf_ktime_get_ns(); - start.update(&pid, &ts); - } - - struct task_struct *next = (struct task_struct *)bpf_get_current_task(); - pid = next->pid; - u64 *tsp = start.lookup(&pid); - if (tsp == 0) return 0; - - start.delete(&pid); - u64 delta = bpf_ktime_get_ns() - *tsp; - delta /= 10000000; - if ((delta < MINBLOCK_US) || (delta > MAXBLOCK_US)) { - return 0; - } - - tgid = next->tgid; - pid_tgid.update(&pid, &tgid); - comm *p = pid_comm.lookup(&pid); - if(!p) { - comm name; - bpf_probe_read_kernel_str(&name, TASK_COMM_LEN, next->comm); - pid_comm.update(&pid, &name); - } - psid key = { - .pid = pid, - .usid = USER_STACK_GET, - .ksid = KERNEL_STACK_GET, - }; - psid_count.increment(key, delta); - - return 0; -} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/bcc/on_cpu_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/bcc/on_cpu_count.bpf.c deleted file mode 100644 index cf9047c0a..000000000 --- a/eBPF_Supermarket/Stack_Analyser/bcc/on_cpu_count.bpf.c +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2023 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 内核态ebpf的cpu占用模块代码 -#include - -typedef struct { - u32 pid; - int32_t ksid, usid; -} psid; - -typedef struct { - char str[TASK_COMM_LEN]; -} comm; - -BPF_HASH(pid_tgid, u32, u32); -BPF_STACK_TRACE(stack_trace, STACK_STORAGE_SIZE); -BPF_HASH(psid_count, psid, u32); -BPF_HASH(pid_comm, u32, comm); - -int do_stack(void *ctx) { - struct task_struct *curr = (struct task_struct *)bpf_get_current_task(); - if(!((THREAD_FILTER) && (STATE_FILTER))) - return -1; - - u32 pid = curr->pid; - u32 tgid = curr->tgid; - pid_tgid.update(&pid, &tgid); - comm *p = pid_comm.lookup(&pid); - if(!p) { - comm name; - bpf_probe_read_kernel_str(&name, TASK_COMM_LEN, curr->comm); - pid_comm.update(&pid, &name); - } - psid apsid = { - .pid = pid, - .ksid = KERNEL_STACK_GET, - .usid = USER_STACK_GET, - }; - psid_count.increment(apsid); - return 0; -} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/bcc/stack_count.py b/eBPF_Supermarket/Stack_Analyser/bcc/stack_count.py deleted file mode 100755 index 5472dd9d4..000000000 --- a/eBPF_Supermarket/Stack_Analyser/bcc/stack_count.py +++ /dev/null @@ -1,325 +0,0 @@ -#!/bin/python - -''' -Copyright 2023 The LMP Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -author: luiyanbing@foxmail.com - -调用栈采集分析脚本 -''' - -from my_format import * -from signal import signal, SIG_IGN -from time import sleep -from bcc import BPF, PerfType, PerfSWConfig -from argparse import ArgumentTypeError, ArgumentParser, RawDescriptionHelpFormatter, SUPPRESS -from subprocess import Popen, PIPE - -mode_list = ['on_cpu', 'off_cpu', 'mem'] - -# arguments -examples = """examples: - sudo -E ./stack_count.py # trace on-CPU stack time until Ctrl-C - sudo -E ./stack_count.py -m off_cpu # trace off-CPU stack time until Ctrl-C - sudo -E ./stack_count.py 5 # trace for 5 seconds only - sudo -E ./stack_count.py -f 5 # 5 seconds, and output as stack_count.svg in flame graph format - sudo -E ./stack_count.py -s 5 # 5 seconds, and show symbol offsets - sudo -E ./stack_count.py -p 185 # only trace threads for PID 185 - sudo -E ./stack_count.py -t 188 # only trace thread 188 - sudo -E ./stack_count.py -c cmdline # only trace threads of cmdline - sudo -E ./stack_count.py -u # only trace user threads (no kernel) - sudo -E ./stack_count.py -k # only trace kernel threads (no user) - sudo -E ./stack_count.py -U # only show user space stacks (no kernel) - sudo -E ./stack_count.py -K # only show kernel space stacks (no user) - sudo -E ./stack_count.py -a # anomaly detection for stack -""" - - -def positive_int(val:str): - try: - ival = int(val) - except ValueError: - raise ArgumentTypeError("must be an integer") - if ival <= 0: - raise ArgumentTypeError("must be positive") - return ival - -def mode_str(val:str): - if val in mode_list: - return val - else: - raise ArgumentTypeError("must be 'on_cpu', 'off_cpu' or 'mem'") - - -parser = ArgumentParser( - description="Summarize on-CPU time by stack trace", - formatter_class=RawDescriptionHelpFormatter, - epilog=examples) - -thread_group = parser.add_mutually_exclusive_group() -# Note: this script provides --pid and --tid flags but their arguments are -# referred to internally using kernel nomenclature: TGID and PID. -thread_group.add_argument("-p", "--pid", metavar="PID", dest="tgid", - help="trace this PID only", type=positive_int) -thread_group.add_argument("-t", "--tid", metavar="TID", dest="pid", - help="trace this TID only", type=positive_int) -thread_group.add_argument("-c", "--cmd", metavar="Command", dest='cmd', - help="trace this command only", type=str) -thread_group.add_argument("-u", "--user-threads-only", action="store_true", - help="user threads only (no kernel threads)") -thread_group.add_argument("-k", "--kernel-threads-only", action="store_true", - help="kernel threads only (no user threads)") - -stack_group = parser.add_mutually_exclusive_group() -stack_group.add_argument("-U", "--user-stacks-only", action="store_true", - help="show stacks from user space only (no kernel space stacks)") -stack_group.add_argument("-K", "--kernel-stacks-only", action="store_true", - help="show stacks from kernel space only (no user space stacks)") - - -parser.add_argument("-a", "--auto", action="store_true", - help="analyzing stacks automatically") -parser.add_argument("-d", "--delimited", action="store_true", - help="insert delimiter between kernel/user stacks") -parser.add_argument("-f", "--folded", action="store_true", - help="output folded format") -parser.add_argument("-s", "--offset", action="store_true", - help="show address offsets") -parser.add_argument("-m", "--mode", default='on_cpu', - type = mode_str, - help="mode of stack counting, 'on_cpu'/'off_cpu'/'mem'") -parser.add_argument("--stack-storage-size", default=16384, - type=positive_int, - help="the number of unique stack traces that can be stored and " - "displayed (default 16384)") -parser.add_argument("duration", nargs="?", default=99999999, - type=positive_int, - help="duration of trace, in seconds") -parser.add_argument("--state", type=positive_int, - help="filter on this thread state bitmask (eg, 2 == TASK_UNINTERRUPTIBLE" + - ") see include/linux/sched.h") -parser.add_argument("--ebpf", action="store_true", - help=SUPPRESS) -args = parser.parse_args() -folded = args.folded -duration = int(args.duration) -mode = args.mode -debug = 0 - -# set thread filter -pid = -1 -thread_context = "" -thread_filter = 'curr->pid' -if args.tgid is not None: - # thread_filter = '!(curr->tgid == %d)' % args.tgid - pid = args.tgid - thread_context = "PID " + str(pid) - if mode == 'off_cpu': - thread_filter = 'curr->tgid == %d' % pid -elif args.pid is not None: - thread_context = "TID %d" % args.pid - thread_filter = 'curr->pid == %d' % args.pid - pid = args.pid -elif args.cmd is not None: - cmd = args.cmd.split() - ps = Popen(cmd) - ps.send_signal(19) - pid = ps.pid - thread_context = "PID " + str(pid) - if mode == 'off_cpu': - thread_filter = 'curr->tgid == %d' % pid - # perf default attach children process -elif args.user_threads_only: - thread_context = "user threads" - thread_filter += ' && curr->flags & PF_KTHREAD' -elif args.kernel_threads_only: - thread_context = "kernel threads" - thread_filter += ' && curr->flags & PF_KTHREAD' -else: - thread_context = "all threads" - -if args.state == 0: - state_filter = 'curr->STATE_FIELD == 0' -elif args.state: - # these states are sometimes bitmask checked - state_filter = 'curr->STATE_FIELD & %d' % args.state -else: - state_filter = '1' - -# stack data ebpf code -from sys import path -with open(path[0]+'/'+mode+'_count.bpf.c', encoding='utf-8') as f: - bpf_text = f.read() - -bpf_text = bpf_text.replace('THREAD_FILTER', thread_filter) -bpf_text = bpf_text.replace('STATE_FILTER', state_filter) - -if BPF.kernel_struct_has_field(b'task_struct', b'__state') == 1: - bpf_text = bpf_text.replace('STATE_FIELD', '__state') -else: - bpf_text = bpf_text.replace('STATE_FIELD', 'state') - -# set stack storage size -bpf_text = bpf_text.replace('STACK_STORAGE_SIZE', str(args.stack_storage_size)) - -# handle stack args -kernel_stack_get = "stack_trace.get_stackid(ctx, 0)" -user_stack_get = "stack_trace.get_stackid(ctx, BPF_F_USER_STACK)" -stack_context = "" -if args.user_stacks_only: - stack_context = "user" - kernel_stack_get = "-1" -elif args.kernel_stacks_only: - stack_context = "kernel" - user_stack_get = "-1" -else: - stack_context = "user + kernel" -bpf_text = bpf_text.replace('USER_STACK_GET', user_stack_get) -bpf_text = bpf_text.replace('KERNEL_STACK_GET', kernel_stack_get) - -need_delimiter = args.delimited and not (args.kernel_stacks_only or - args.user_stacks_only) - -if args.kernel_threads_only and args.user_stacks_only: - from sys import stderr - print("ERROR: Displaying user stacks for kernel threads " + - "doesn't make sense.", file=stderr) - exit(2) - -if debug or args.ebpf: - print(bpf_text) - if args.ebpf: - print("ERROR: Exiting") - exit(3) - -if args.folded and args.offset: - print("ERROR: can only use -f or -s. Exiting.") - exit() - -show_offset = False -if args.offset: - show_offset = True - -auto = False -if args.auto: - auto = True - from my_ad import adc - ado = adc() - - -ad = False -if auto and not args.pid and not args.tgid and not args.cmd: - ad = True - -# bpf parsing -b = BPF(text=bpf_text) -print("eBPF initializing compelete.") -match mode: - case 'on_cpu': - b.attach_perf_event(ev_type=PerfType.SOFTWARE, - ev_config=PerfSWConfig.CPU_CLOCK, fn_name="do_stack", - sample_period=0, sample_freq=99, pid=pid) - case 'off_cpu': - b.attach_kprobe( - event_re="^finish_task_switch$|^finish_task_switch\.isra\.\d$", fn_name='do_stack') - case 'mem': - arch = Popen(args='uname -m', stdout=PIPE, shell=True).stdout.read().decode().split()[0] - lib = "/usr/lib/"+arch+"-linux-gnu/libc.so.6" - # if pid != -1: - # from psutil import Process - # lib = Process(pid).exe() - b.attach_uprobe(name=lib, sym='malloc', fn_name='malloc_enter', pid=pid) - b.attach_uretprobe(name=lib, sym='malloc', fn_name='malloc_exit', pid=pid) - b.attach_uprobe(name=lib, sym='free', fn_name='free_enter', pid=pid) - - -if pid != -1: - print("attach %d." % pid) - # add external sym - try: - from psutil import Process - b.add_module(Process(pid).exe()) - except: - print("failed to load syms of pid %d" % pid) -else: - print("attach all processes") - - -def int_handler(sig=None, frame=None): - print("\b\bquit...") - match mode: - case 'on_cpu': - b.detach_perf_event(ev_type=PerfType.SOFTWARE, - ev_config=PerfSWConfig.CPU_CLOCK) - case 'off_cpu': - for tp in b.get_kprobe_functions(b"^finish_task_switch$|^finish_task_switch\.isra\.\d$"): - b.detach_kprobe(tp) - case 'mem': - try: - b.detach_uprobe(lib, 'malloc') - b.detach_uretprobe(lib, 'malloc') - b.detach_uprobe(lib, 'free') - except: - pass - - # system("tput rmcup") - if auto: - if not ad: - ado.auto_label(b) - ado.avg_mutant() - get_mutant = ado.get_mutant - else: - get_mutant = lambda _:0 - - tgids = map2dict(b, get_mutant, need_delimiter, show_offset) - print("save to stack_count.json...") - with open("stack_count.json", "w") as file: - file.write(dumps(tgids, cls=MyEncoder, indent=2, ensure_ascii=True, - sort_keys=False, separators=(',', ':'))) - if auto: - print("calc ad performance...") - from my_ad import rate - from re import match - rate(tgids, lambda x: match(r'stress-ng-.*', x)) - if folded: - print("save to stack_count.svg...") - fla_text(b, need_delimiter) - exit() - -# system("tput -x smcup; clear") -if args.cmd != None: - signal(2, lambda *_: ps.kill) - signal(1, lambda *_: ps.kill) - ps.send_signal(18) - d = 0 - while ps.poll() == None and d <= duration: - sleep(5) - d += 5 - if ad: - ado.ad_log(b) - signal(2, SIG_IGN) - signal(1, SIG_IGN) - ps.kill() - int_handler() -else: - signal(2, int_handler) - signal(1, int_handler) - for _ in range(duration//5): - sleep(5) - if ad: - ado.ad_log(b) - signal(2, SIG_IGN) - signal(1, SIG_IGN) - int_handler() diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/IOStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/IOStackCollector.h new file mode 100644 index 000000000..5761cf425 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf/IOStackCollector.h @@ -0,0 +1,41 @@ +#ifndef _SA_IO_H__ +#define _SA_IO_H__ + +#include +typedef struct +{ + __u64 size : 40; + __u64 count : 24; +} io_tuple; + +#ifdef __cplusplus +#include "bpf/io_count.skel.h" +#include "bpf/eBPFStackCollector.h" + +class IOStackCollector : public StackCollector +{ +private: + declareEBPF(io_count_bpf); + +public: + enum io_mod + { + COUNT, + SIZE, + AVE, + } DataType = COUNT; + +protected: + virtual double count_value(void *); + +public: + void setScale(io_mod mod); + IOStackCollector(); + virtual int load(void); + virtual int attach(void); + virtual void detach(void); + virtual void unload(void); +}; +#endif + +#endif \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/MemoryStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/MemoryStackCollector.h new file mode 100644 index 000000000..70dcf9715 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf/MemoryStackCollector.h @@ -0,0 +1,90 @@ +#ifndef _SA_MEMORY_H__ +#define _SA_MEMORY_H__ + +#include "bpf/eBPFStackCollector.h" +#include "bpf/mem_count.skel.h" +#include + +class MemoryStackCollector : public StackCollector +{ +private: + struct mem_count_bpf *skel = __null; + +public: + char *object = (char *)"libc.so.6"; + +protected: + virtual double count_value(void *d); + +public: + MemoryStackCollector(); + + virtual int load(void); + virtual int attach(void); + virtual void detach(void); + virtual void unload(void); + +/// @brief 向指定用户函数附加一个ebpf处理函数 +/// @param skel ebpf程序骨架 +/// @param sym_name 用户态函数名字面量,不加双引号 +/// @param prog_name ebpf处理函数,skel->progs中的成员名 +/// @param is_retprobe 布尔类型,是否附加到符号返回处 +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0) +#define ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe) \ + do \ + { \ + DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts, \ + .retprobe = is_retprobe); \ + skel->links.prog_name = bpf_program__attach_uprobe_opts( \ + skel->progs.prog_name, \ + pid, \ + object, \ + 1, \ + &uprobe_opts); \ + } while (false) +#else +#define ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe) \ + do \ + { \ + LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts, \ + .retprobe = is_retprobe, \ + .func_name = #sym_name); \ + skel->links.prog_name = \ + bpf_program__attach_uprobe_opts( \ + skel->progs.prog_name, \ + pid, \ + object, \ + 0, \ + &uprobe_opts); \ + } while (false) +#endif + +/// @brief 向指定用户函数附加一个处理函数并检查是否连接成功 +/// @param skel ebpf程序骨架 +/// @param sym_name 要连接的用户函数 +/// @param prog_name ebpf处理函数 +/// @param is_retprobe 布尔类型,是否附加到函数返回处 +/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 +#define ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, is_retprobe) \ + do \ + { \ + ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe); \ + CHECK_ERR(!skel->links.prog_name, "no program attached for " #prog_name "\n") \ + } while (false) + +/// @brief 向指定用户态函数入口处附加一个处理函数并检查是否连接成功 +/// @param skel ebpf程序骨架 +/// @param sym_name 要跟踪的用户态函数名字面量,不带双引号 +/// @param prog_name ebpf处理函数,skel->progs中的成员 +/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 +#define at_ent(skel, sym_name, prog_name) ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, false) + +/// @brief 向指定用户态函数返回处附加一个处理函数并检查是否连接成功 +/// @param skel ebpf程序骨架 +/// @param sym_name 要附加的用户态函数名,字面量,不带双引号 +/// @param prog_name ebpf处理函数,skel->progs中的成员 +/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 +#define at_ret(skel, sym_name, prog_name) ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, true) +}; + +#endif diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/OffCPUStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/OffCPUStackCollector.h new file mode 100644 index 000000000..6d3084870 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf/OffCPUStackCollector.h @@ -0,0 +1,23 @@ +#ifndef _SA_OFF_CPU_H__ +#define _SA_OFF_CPU_H__ + +#include "bpf/eBPFStackCollector.h" +#include "bpf/off_cpu_count.skel.h" + +class OffCPUStackCollector : public StackCollector +{ +private: + struct off_cpu_count_bpf *skel = __null; + +protected: + virtual double count_value(void*); + +public: + OffCPUStackCollector(); + virtual int load(void); + virtual int attach(void); + virtual void detach(void); + virtual void unload(void); +}; + +#endif \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/OnCPUStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/OnCPUStackCollector.h new file mode 100644 index 000000000..65f209a59 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf/OnCPUStackCollector.h @@ -0,0 +1,32 @@ +#ifndef _SA_ON_CPU_H__ +#define _SA_ON_CPU_H__ + +#include "eBPFStackCollector.h" +#include "on_cpu_count.skel.h" + + +#ifdef __cplusplus +class OnCPUStackCollector : public StackCollector +{ +private: + struct on_cpu_count_bpf *skel = __null; + + int *pefds = NULL; + int num_cpus = 0; + struct bpf_link **links = NULL; + unsigned long long freq = 49; + +protected: + virtual double count_value(void *); + +public: + void setScale(uint64_t freq); + OnCPUStackCollector(); + virtual int load(void); + virtual int attach(void); + virtual void detach(void); + virtual void unload(void); +}; +#endif + +#endif \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/ProbeStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/ProbeStackCollector.h new file mode 100644 index 000000000..90c80fbab --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf/ProbeStackCollector.h @@ -0,0 +1,22 @@ +#include "bpf/eBPFStackCollector.h" +#include "bpf/stack_count.skel.h" + +class StackCountStackCollector : public StackCollector +{ +private: + struct stack_count_bpf *skel = __null; + +public: + std::string probe; + +protected: + virtual double count_value(void *); + +public: + void setScale(std::string probe); + StackCountStackCollector(); + virtual int load(void); + virtual int attach(void); + virtual void detach(void); + virtual void unload(void); +}; diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/ReadaheadStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/ReadaheadStackCollector.h new file mode 100644 index 000000000..6df11f971 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf/ReadaheadStackCollector.h @@ -0,0 +1,32 @@ +#ifndef _SA_READAHEAD_H__ +#define _SA_READAHEAD_H__ + +#include +typedef struct +{ + __u32 expect; + __u32 truth; +} ra_tuple; + +#ifdef __cplusplus +#include "bpf/pre_count.skel.h" +#include "bpf/eBPFStackCollector.h" + +class ReadaheadStackCollector : public StackCollector +{ +private: + declareEBPF(pre_count_bpf); + +protected: + virtual double count_value(void *data); + +public: + ReadaheadStackCollector(); + virtual int load(void); + virtual int attach(void); + virtual void detach(void); + virtual void unload(void); +}; +#endif + +#endif \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/TemplateClass.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/TemplateClass.h new file mode 100644 index 000000000..9b464e9bb --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf/TemplateClass.h @@ -0,0 +1,31 @@ +#ifndef _TEMPLATE_H__ +#define _TEMPLATE_H__ + +// ========== C code part ========== + +// ========== C code end ========== + +#ifdef __cplusplus +// ========== C++ code part ========== +#include "bpf/template.skel.h" +#include "bpf/eBPFStackCollector.h" + +class TemplateClass : public StackCollector +{ +private: + declareEBPF(template_bpf); + +protected: + virtual double count_value(void *); + +public: + TemplateClass(); + virtual int load(void); + virtual int attach(void); + virtual void detach(void); + virtual void unload(void); +}; +// ========== C++ code end ========== +#endif + +#endif \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/eBPFStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/eBPFStackCollector.h new file mode 100644 index 000000000..70ccd56d0 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf/eBPFStackCollector.h @@ -0,0 +1,125 @@ +#ifndef _SA_STACK_COLLECTOR_H__ +#define _SA_STACK_COLLECTOR_H__ + +#include +#include +#include +#include +#include "sa_user.h" + +struct Scale +{ + const char *Type, *Unit; + int64_t Period; +}; + +/// @brief count类,主要是为了重载比较运算,便于自动排序 +struct CountItem +{ + psid k; + double v; + CountItem(psid k, double v) : k(k), v(v){}; + + /// @brief count对象的大小取决于val的大小 + /// @param b 要比较的对象 + /// @return 小于b则为真,否则为假 + friend bool operator<(const CountItem a, const CountItem b); +}; + +class StackCollector +{ +protected: + struct bpf_object *obj = NULL; + + // 默认显示计数的变化情况,即每次输出数据后清除计数 + bool showDelta = true; + +public: + Scale scale = {0}; + + int pid = -1; // 用于设置ebpf程序跟踪的pid + int err = 0; // 用于保存错误代码 + + bool ustack = true; // 是否跟踪用户栈 + bool kstack = true; // 是否跟踪内核栈 + uint64_t min = 0; + uint64_t max = __UINT64_MAX__; // 设置采集指标最大值,最小值 + + int self_pid = -1; + +protected: + std::vector *sortedCountList(void); + + /// @brief 将缓冲区的数据解析为特定值 + /// @param 无 + /// @return 解析出的值 + virtual double count_value(void *data) = 0; + +public: + StackCollector(); + operator std::string(); + + /// @brief 负责ebpf程序的加载、参数设置和打开操作 + /// @param 无 + /// @return 成功则返回0,否则返回负数 + virtual int load(void) = 0; + + /// @brief 将ebpf程序挂载到跟踪点上 + /// @param 无 + /// @return 成功则返回0,否则返回负数 + virtual int attach(void) = 0; + + /// @brief 断开ebpf的跟踪点和处理函数间的连接 + /// @param 无 + virtual void detach(void) = 0; + + /// @brief 卸载ebpf程序 + /// @param 无 + virtual void unload(void) = 0; + +// 声明eBPF骨架 +#define declareEBPF(eBPFName) struct eBPFName *skel = NULL; + +/// @brief 加载、初始化参数并打开指定类型的ebpf程序 +/// @param ... 一些ebpf程序全局变量初始化语句 +/// @note 失败会使上层函数返回-1 +#define StackProgLoadOpen(...) \ + { \ + skel = skel->open(NULL); \ + CHECK_ERR(!skel, "Fail to open BPF skeleton"); \ + skel->bss->min = min; \ + skel->bss->max = max; \ + skel->bss->u = ustack; \ + skel->bss->k = kstack; \ + skel->bss->self_pid = self_pid; \ + __VA_ARGS__; \ + err = skel->load(skel); \ + CHECK_ERR(err, "Fail to load BPF skeleton"); \ + obj = skel->obj; \ + } + +#define defaultAttach \ + { \ + err = skel->attach(skel); \ + CHECK_ERR(err, "Failed to attach BPF skeleton"); \ + } + +#define defaultDetach \ + { \ + if (skel) \ + { \ + skel->detach(skel); \ + } \ + } + +#define defaultUnload \ + { \ + if (skel) \ + { \ + skel->destroy(skel); \ + } \ + skel = NULL; \ + } +}; + +#endif \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/include/clipp.h b/eBPF_Supermarket/Stack_Analyser/include/clipp.h similarity index 100% rename from eBPF_Supermarket/Stack_Analyser/libbpf/include/clipp.h rename to eBPF_Supermarket/Stack_Analyser/include/clipp.h diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/include/elf.h b/eBPF_Supermarket/Stack_Analyser/include/elf.hpp similarity index 100% rename from eBPF_Supermarket/Stack_Analyser/libbpf/include/elf.h rename to eBPF_Supermarket/Stack_Analyser/include/elf.hpp diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/include/sa_common.h b/eBPF_Supermarket/Stack_Analyser/include/sa_common.h similarity index 89% rename from eBPF_Supermarket/Stack_Analyser/libbpf/include/sa_common.h rename to eBPF_Supermarket/Stack_Analyser/include/sa_common.h index a142fa261..5735de509 100644 --- a/eBPF_Supermarket/Stack_Analyser/libbpf/include/sa_common.h +++ b/eBPF_Supermarket/Stack_Analyser/include/sa_common.h @@ -36,14 +36,4 @@ typedef struct { char str[COMM_LEN]; } comm; -typedef struct { - __u64 truth; - __u64 expect; -} ra_tuple; - -typedef struct { - __u64 count; - __u64 size; -} io_tuple; - #endif \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/include/sa_ebpf.h b/eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h similarity index 100% rename from eBPF_Supermarket/Stack_Analyser/libbpf/include/sa_ebpf.h rename to eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h diff --git a/eBPF_Supermarket/Stack_Analyser/include/sa_user.h b/eBPF_Supermarket/Stack_Analyser/include/sa_user.h new file mode 100644 index 000000000..cee3b9c19 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/include/sa_user.h @@ -0,0 +1,54 @@ +// Copyright 2023 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// 用户态使用的宏 + +#ifndef STACK_ANALYZER_USER +#define STACK_ANALYZER_USER + +#include +#include +#include +#include +#include +#include + +#include "sa_common.h" + +/// @brief 检查错误,若错误成立则打印带原因的错误信息并使上层函数返回-1 +/// @param cond 被检查的条件表达式 +/// @param info 要打印的错误信息 +#define CHECK_ERR(cond, ...) \ + if (cond) \ + { \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, " [%s]\n", strerror(errno)); \ + return -1; \ + } + +#include +/// @brief 检查错误,若错误成立则打印带原因的错误信息并退出 +/// @param cond 被检查的条件表达式 +/// @param info 要打印的错误信息 +#define CHECK_ERR_EXIT(cond, ...) \ + if (cond) \ + { \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, " [%s]\n", strerror(errno)); \ + exit(EXIT_FAILURE); \ + } + +#endif diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/include/symbol.h b/eBPF_Supermarket/Stack_Analyser/include/symbol.h similarity index 100% rename from eBPF_Supermarket/Stack_Analyser/libbpf/include/symbol.h rename to eBPF_Supermarket/Stack_Analyser/include/symbol.h diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/include/task.h b/eBPF_Supermarket/Stack_Analyser/include/task.h similarity index 100% rename from eBPF_Supermarket/Stack_Analyser/libbpf/include/task.h rename to eBPF_Supermarket/Stack_Analyser/include/task.h diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/README.md b/eBPF_Supermarket/Stack_Analyser/libbpf/README.md deleted file mode 100644 index 8e9894017..000000000 --- a/eBPF_Supermarket/Stack_Analyser/libbpf/README.md +++ /dev/null @@ -1,218 +0,0 @@ -### 安装依赖 - -```shell -$ git submodule update --init --recursive -$ apt install clang libelf1 libelf-dev zlib1g-dev -``` - -### 版本要求 - -Linux 5.15以上 -g++-10以上 -clang-12以上 - -### 工具编译 - -客户端编译: - -```shell -$ make -``` - -服务器端编译: - -```shell -$ g++ server.cpp -o server -``` - -### 命令使用方法 - -客户端: - -```shell -$ ./stack_analyzer -h -SYNOPSIS - ./stack_analyzer ([-p ] | [-c ]) [-d ] [-l] [-t ] [-s ] [-v] [on-cpu [-F ] [-U] [-K] - [-m ] [-n ]] [off-cpu [-U] [-K] [-m ] [-n ]] [mem [-U] [-K] [-m ] [-n ]] [io [--mod [count|ave|size]] - [-U] [-K] [-m ] [-n ]] [ra [-U] [-K] [-m ] [-n - ]] - -OPTIONS - statistic call trace relate with some metrics - -p, --pid - set pid of process to monitor - - -c, --command - set command for monitoring the whole life - - -d, --delay - set the interval to output - - -l, --realtime-list - output in console, default false - - - set the total simpling time - - - set the server address - - -v, --version - show version - - on-cpu sample the call stacks of on-cpu processes - - sampling at a set frequency - - -U, --user-stack-only - only sample user stacks - - -K, --kernel-stack-only - only sample kernel stacks - - -m, --max-value - set the max threshold of sampled value - - -n, --min-value - set the min threshold of sampled value - - off-cpu sample the call stacks of off-cpu processes - -U, --user-stack-only - only sample user stacks - - -K, --kernel-stack-only - only sample kernel stacks - - -m, --max-value - set the max threshold of sampled value - - -n, --min-value - set the min threshold of sampled value - - mem sample the memory usage of call stacks - -U, --user-stack-only - only sample user stacks - - -K, --kernel-stack-only - only sample kernel stacks - - -m, --max-value - set the max threshold of sampled value - - -n, --min-value - set the min threshold of sampled value - - io sample the IO data volume of call stacks - --mod [count|ave|size] - set the statistic mod - - -U, --user-stack-only - only sample user stacks - - -K, --kernel-stack-only - only sample kernel stacks - - -m, --max-value - set the max threshold of sampled value - - -n, --min-value - set the min threshold of sampled value - - ra sample the readahead hit rate of call stacks - -U, --user-stack-only - only sample user stacks - - -K, --kernel-stack-only - only sample kernel stacks - - -m, --max-value - set the max threshold of sampled value - - -n, --min-value - set the min threshold of sampled value -``` - -服务器端: - -```shell -$ ./server [port for listening, default 12345] -``` - -### 运行效果 - -开启服务器端,然后开启客户端,以on-cpu子功能为例: - -服务器端: - -```shell -$ ./server -等待客户端连接... -客户端连接成功 -on_cpu_stack_data.log -on_cpu_stack_data.log -on_cpu_stack_data.log -on_cpu_stack_data.log -连接关闭或出现错误 -客户端连接成功 -on_cpu_stack_data.log -on_cpu_stack_data.log -连接关闭或出现错误 -^C -$ -``` - -客户端: - -```shell -$ sudo ./stack_analyzer on-cpu -display mode: 0 -Thu Jan 4 19:45:03 2024 -Thu Jan 4 19:45:09 2024 -Thu Jan 4 19:45:14 2024 -Thu Jan 4 19:45:19 2024 -^C -$ sudo ./stack_analyzer on-cpu -display mode: 0 -Thu Jan 4 19:45:45 2024 -Thu Jan 4 19:45:51 2024 -^C -$ -``` - -保存的数据如下所示: - -```log -cpptools:3394;sqlite3BtreeTableMoveto+0x7f677fa00000;---------;[MISSING KERNEL STACK]; 2 -``` - -第一个分号前是命令名以及pid,之后是用户栈及内核栈,由“---------”分隔,末尾是调用栈对应的指标值,on-cpu子功能中表示5s内的定频采样数。 - -若客户端没有探测到服务端,则客户端会将数据存储在本地,并输出列表: - -```shell -$ sudo ./stack_analyzer on-cpu -display mode: 0 -Error connecting to server -Thu Jan 4 20:45:45 2024 -pid:24647 usid:56144 ksid:65341 value:1.00 -pid:23844 usid:-14 ksid:127594 value:1.00 -pid:14297 usid:84638 ksid:47805 value:1.00 -pid:24658 usid:96121 ksid:-14 value:1.00 -pid:9577 usid:16299 ksid:-14 value:1.00 -pid:9577 usid:21537 ksid:-14 value:1.00 -pid:9581 usid:34778 ksid:-14 value:1.00 -pid:9582 usid:3180 ksid:-14 value:1.00 -pid:24650 usid:71768 ksid:-14 value:1.00 -Thu Jan 4 20:45:51 2024 -pid:24647 usid:56144 ksid:65341 value:1.00 -pid:23844 usid:-14 ksid:127594 value:1.00 -pid:24671 usid:22828 ksid:70105 value:1.00 -pid:14297 usid:84638 ksid:47805 value:1.00 -``` \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/bpf/pre_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/libbpf/bpf/pre_count.bpf.c deleted file mode 100644 index c2da7829c..000000000 --- a/eBPF_Supermarket/Stack_Analyser/libbpf/bpf/pre_count.bpf.c +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright 2023 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 内核态bpf的预读取分析模块代码 - -#include "vmlinux.h" -#include -#include -#include - -#include "sa_ebpf.h" -#include "task.h" - -#define MINBLOCK_US 1ULL -#define MAXBLOCK_US 99999999ULL - -DeclareCommonMaps(ra_tuple); -DeclareCommonVar(); - -int apid = 0; -BPF_HASH(in_ra, u32, psid); -BPF_HASH(page_psid, struct page *, psid); - -SEC("fentry/page_cache_ra_unbounded") //fentry在内核函数page_cache_ra_unbounded进入时触发的挂载点 -int BPF_PROG(page_cache_ra_unbounded) -{ - struct task_struct* curr = (struct task_struct*)bpf_get_current_task(); - ignoreKthread(curr); - u32 pid = get_task_ns_pid(curr); //获取当前进程tgid,用户空间的pid即是tgid - - if ((apid >= 0 && pid != apid) || !pid || pid == self_pid) - return 0; - - u32 tgid = get_task_ns_tgid(curr); - bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); //更新pid_tgid表中的pid对应的值 - comm *p = bpf_map_lookup_elem(&pid_comm, &pid); //p指向pid_comm表中pid对应的值 - if (!p) - { - comm name; - bpf_get_current_comm(&name, COMM_LEN); //获取当前进程名 - bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST); //在pid_comm表中更新pid对应的值 - } - - psid apsid = { - .pid = pid, - .usid = u ? USER_STACK : -1, - .ksid = k ? KERNEL_STACK : -1, - }; - - ra_tuple *d = bpf_map_lookup_elem(&psid_count, &apsid); //d指向psid_count表中的apsid对应的类型为tuple的值 - if (!d) - { - ra_tuple a = {.expect = 0, .truth = 0}; //初始化为0 - bpf_map_update_elem(&psid_count, &apsid, &a, BPF_ANY); //更新psid_count表中的apsid的值为a - } - bpf_map_update_elem(&in_ra, &pid, &apsid, BPF_ANY); //更新in_ra表中的pid对应的值为apsid - return 0; -} - - -SEC("fexit/alloc_pages") //fexit在内核函数alloc_pages退出时触发,挂载点为alloc_pages -int BPF_PROG(filemap_alloc_folio_ret, gfp_t gfp, unsigned int order, u64 ret) -{ - u32 pid = bpf_get_current_pid_tgid() >> 32; //pid为当前进程的pid - - if ((apid >= 0 && pid != apid) || !pid) - return 0; - - struct psid *apsid = bpf_map_lookup_elem(&in_ra, &pid); //apsid指向了当前in_ra中pid的表项内容 - if (!apsid) - return 0; - - ra_tuple *a = bpf_map_lookup_elem(&psid_count, apsid); //a是指向psid_count的apsid对应的内容 - if (!a) - return 0; - - const u32 lim = 1ul << order; //1 为长整型,左移order位,即2^order 即申请页的大小 - a->expect += lim; //a->expect+=页大小(未访问) - u64 addr; - bpf_core_read(&addr, sizeof(u64), &ret); //alloc_pages返回的值,即申请页的起始地址保存在addr中 - for (int i = 0; i < lim && i < 1024; i++, addr += 0x1000) - bpf_map_update_elem(&page_psid, &addr, apsid, BPF_ANY);//更新page_psid表中的addr(从页的起始地址开始到页的结束地址)所对应的值为apsid - - return 0; -} - -SEC("fexit/page_cache_ra_unbounded") -int BPF_PROG(page_cache_ra_unbounded_ret) //fexit在内核函数page_cache_ra_unbounded退出时触发的挂载点 -{ - u32 pid = bpf_get_current_pid_tgid() >> 32; //获取当前进程的pid - - if ((apid >= 0 && pid != apid) || !pid) - return 0; - - bpf_map_delete_elem(&in_ra, &pid); //删除了in_ra对应的pid的表项,即删除对应的栈计数信息 - return 0; -} - - -SEC("fentry/mark_page_accessed") //fentry在内核函数/mark_page_accessed进入时触发的挂载点,用于标记页面(page)已经被访问 -int BPF_PROG(mark_page_accessed, u64 page) -{ - u32 pid = bpf_get_current_pid_tgid() >> 32; //获取当前进程的pid - - if ((apid >= 0 && pid != apid) || !pid) - return 0; - psid *apsid; - apsid = bpf_map_lookup_elem(&page_psid, &page); //查看page_psid对应的 地址page 对应类型为psid的值,并保存在apsid - if (!apsid) - return 0; - ra_tuple *a = bpf_map_lookup_elem(&psid_count, apsid); //a指向psid_count的apsid的内容 - if (!a) - return 0; - a->truth++; //已访问 - bpf_map_delete_elem(&page_psid, &page); //删除page_psid的page对应的内容 - return 0; -} - -const char LICENSE[] SEC("license") = "GPL"; \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/include/sa_user.h b/eBPF_Supermarket/Stack_Analyser/libbpf/include/sa_user.h deleted file mode 100644 index 790341cc9..000000000 --- a/eBPF_Supermarket/Stack_Analyser/libbpf/include/sa_user.h +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright 2023 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 用户态使用的宏 - -#ifndef STACK_ANALYZER_USER -#define STACK_ANALYZER_USER - -#include -#include -#include -#include -#include -#include -#include - -#include "sa_common.h" - -struct Scale { - const char *Type, *Unit; - int64_t Period; -}; - -/// @brief 获取epbf程序中指定表的文件描述符 -/// @param name 表的名字 -#define OPEN_MAP(name) bpf_map__fd(skel->maps.name) - -/// @brief 获取所有表的文件描述符 -#define OPEN_ALL_MAP() \ - value_fd = OPEN_MAP(psid_count); \ - tgid_fd = OPEN_MAP(pid_tgid); \ - comm_fd = OPEN_MAP(pid_comm); \ - trace_fd = OPEN_MAP(stack_trace); - -/// @brief 加载、初始化参数并打开指定类型的ebpf程序 -/// @param ... 一些ebpf程序全局变量初始化语句 -/// @note 失败会使上层函数返回-1 -#define StackProgLoadOpen(...) \ - skel = skel->open(NULL); \ - CHECK_ERR(!skel, "Fail to open BPF skeleton"); \ - skel->bss->min = min; \ - skel->bss->max = max; \ - skel->bss->u = ustack; \ - skel->bss->k = kstack; \ - skel->bss->self_pid = self_pid; \ - __VA_ARGS__; \ - err = skel->load(skel); \ - CHECK_ERR(err, "Fail to load BPF skeleton"); \ - OPEN_ALL_MAP() - -/// @brief 检查错误,若错误成立则打印带原因的错误信息并使上层函数返回-1 -/// @param cond 被检查的条件表达式 -/// @param info 要打印的错误信息 -#define CHECK_ERR(cond, ...) \ - if (cond) \ - { \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, " [%s]\n", strerror(errno)); \ - return -1; \ - } - -#include -/// @brief 检查错误,若错误成立则打印带原因的错误信息并退出 -/// @param cond 被检查的条件表达式 -/// @param info 要打印的错误信息 -#define CHECK_ERR_EXIT(cond, ...) \ - if (cond) \ - { \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, " [%s]\n", strerror(errno)); \ - exit(EXIT_FAILURE); \ - } - -#include -#include -/// @brief staring perf event -/// @param hw_event attribution of the perf event -/// @param pid the pid to track. 0 for the calling process. -1 for all processes. -/// @param cpu the cpu to track. -1 for all cpu -/// @param group_fd fd of event group leader -/// @param flags setting -/// @return fd of perf event -static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, - unsigned long flags) -{ - return syscall(SYS_perf_event_open, hw_event, pid, cpu, group_fd, flags); -} - -extern int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz); - -/// @brief 向指定用户函数附加一个ebpf处理函数 -/// @param skel ebpf程序骨架 -/// @param sym_name 用户态函数名字面量,不加双引号 -/// @param prog_name ebpf处理函数,skel->progs中的成员名 -/// @param is_retprobe 布尔类型,是否附加到符号返回处 -#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0) -#define __ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe) \ - do \ - { \ - DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts, \ - .retprobe = is_retprobe); \ - skel->links.prog_name = bpf_program__attach_uprobe_opts( \ - skel->progs.prog_name, \ - pid, \ - object, \ - 1, \ - &uprobe_opts); \ - } while (false) -#else -#define __ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe) \ - do \ - { \ - LIBBPF_OPTS( \ - bpf_uprobe_opts, uprobe_opts, \ - .retprobe = is_retprobe, \ - .func_name = #sym_name); \ - skel->links.prog_name = bpf_program__attach_uprobe_opts( \ - skel->progs.prog_name, \ - pid, \ - object, \ - 0, \ - &uprobe_opts); \ - } while (false) -#endif - -/// @brief 检查处理函数是否已经被附加到函数上 -/// @param skel ebpf程序骨架 -/// @param prog_name ebpf处理函数 -/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 -#define __CHECK_PROGRAM(skel, prog_name) \ - do \ - { \ - if (!skel->links.prog_name) \ - { \ - fprintf(stderr, "[%s] no program attached for" #prog_name "\n", strerror(errno)); \ - return -errno; \ - } \ - } while (false) - -/// @brief 向指定用户函数附加一个处理函数并检查是否连接成功 -/// @param skel ebpf程序骨架 -/// @param sym_name 要连接的用户函数 -/// @param prog_name ebpf处理函数 -/// @param is_retprobe 布尔类型,是否附加到函数返回处 -/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 -#define __ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, is_retprobe) \ - do \ - { \ - __ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe); \ - __CHECK_PROGRAM(skel, prog_name); \ - } while (false) - -/// @brief 向指定用户态函数入口处附加一个处理函数 -/// @param skel ebpf程序骨架 -/// @param sym_name 要附加的用户态函数名 -/// @param prog_name ebpf处理函数 -#define ATTACH_UPROBE(skel, sym_name, prog_name) __ATTACH_UPROBE(skel, sym_name, prog_name, false) - -/// @brief 向指定用户态函数返回处附加一个处理函数 -/// @param skel ebpf程序骨架 -/// @param sym_name 用户态函数名 -/// @param prog_name ebpf处理函数 -#define ATTACH_URETPROBE(skel, sym_name, prog_name) __ATTACH_UPROBE(skel, sym_name, prog_name, true) - -/// @brief 向指定用户态函数入口处附加一个处理函数并检查是否连接成功 -/// @param skel ebpf程序骨架 -/// @param sym_name 要跟踪的用户态函数名字面量,不带双引号 -/// @param prog_name ebpf处理函数,skel->progs中的成员 -/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 -#define ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name) __ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, false) - -/// @brief 向指定用户态函数返回处附加一个处理函数并检查是否连接成功 -/// @param skel ebpf程序骨架 -/// @param sym_name 要附加的用户态函数名,字面量,不带双引号 -/// @param prog_name ebpf处理函数,skel->progs中的成员 -/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 -#define ATTACH_URETPROBE_CHECKED(skel, sym_name, prog_name) __ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, true) - -#endif diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/libbpf-bootstrap b/eBPF_Supermarket/Stack_Analyser/libbpf/libbpf-bootstrap deleted file mode 160000 index dfda8587c..000000000 --- a/eBPF_Supermarket/Stack_Analyser/libbpf/libbpf-bootstrap +++ /dev/null @@ -1 +0,0 @@ -Subproject commit dfda8587c6a70d98897ac71780e5f9c668ded187 diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/stack_analyzer.cc b/eBPF_Supermarket/Stack_Analyser/libbpf/stack_analyzer.cc deleted file mode 100644 index 1a0850b9a..000000000 --- a/eBPF_Supermarket/Stack_Analyser/libbpf/stack_analyzer.cc +++ /dev/null @@ -1,852 +0,0 @@ -// Copyright 2023 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 用户态bpf的主程序代码,主要用于数据的显示和整理 - -#include -#include -#include -#include - -#include "include/symbol.h" -#include "include/clipp.h" - -extern "C" -{ -#include -#include -#include -#include -#include - -#include "include/sa_user.h" -#include "bpf/on_cpu_count.skel.h" -#include "bpf/off_cpu_count.skel.h" -#include "bpf/mem_count.skel.h" -#include "bpf/io_count.skel.h" -#include "bpf/pre_count.skel.h" -#include "bpf/stack_count.skel.h" -} - -std::string getLocalDateTime(void) -{ - auto t = time(NULL); - auto localTm = localtime(&t); - char buff[32]; - strftime(buff, 32, "%Y%m%d_%H_%M_%S", localTm); - return std::string(buff); -} - -// 模板用来统一调用多个类有同样但未被抽象的接口 -// 虚函数用来规范接口来被统一调用 - -class StackCollector -{ -private: - /// @brief count类,主要是为了重载比较运算,便于自动排序 - class CountItem - { - public: - uint32_t pid; - int32_t ksid, usid; - double val; - CountItem(int32_t p, int32_t k, int32_t u, double v) - { - - pid = p; - ksid = k; - usid = u; - val = v; - }; - - /// @brief count对象的大小取决于val的大小 - /// @param b 要比较的对象 - /// @return 小于b则为真,否则为假 - bool operator<(const CountItem b) - { - return val < b.val; - }; - }; - - /// @brief 从count_map中取出数据并按val值生成有序列表 - /// @return 一个列表指针 - std::vector *sortedCountList(void) - { - if (value_fd < 0) - { - return NULL; - } - auto keys = new psid[MAX_ENTRIES]; - auto vals = new char[MAX_ENTRIES * count_size]; - uint32_t count = MAX_ENTRIES; - psid next_key; - int err; - if (showDelta) - { - err = bpf_map_lookup_and_delete_batch(value_fd, NULL, &next_key, keys, vals, &count, NULL); - } - else - { - err = bpf_map_lookup_batch(value_fd, NULL, &next_key, keys, vals, &count, NULL); - } - if (err == EFAULT) - { - return NULL; - } - - auto D = new std::vector(); - for (uint32_t i = 0; i < count; i++) - { - CountItem d(keys[i].pid, keys[i].ksid, keys[i].usid, data_value(vals + count_size * i)); - D->insert(std::lower_bound(D->begin(), D->end(), d), d); - } - delete[] keys; - delete[] vals; - return D; - }; - -protected: - int value_fd = -1; // 栈计数表的文件描述符 - int tgid_fd = -1; // pid-tgid表的文件描述符 - int comm_fd = -1; // pid-进程名表的文件描述符 - int trace_fd = -1; // 栈id-栈轨迹表的文件描述符 - - // 计数变量类型默认为u32 - size_t count_size = sizeof(uint32_t); - - // 默认显示计数的变化情况,即每次输出数据后清除计数 - bool showDelta = true; - - /// @brief 将缓冲区的数据解析为特定值,默认解析为u32 - /// @param 无 - /// @return 解析出的值 - virtual double data_value(void *data) - { - return *(uint32_t *)data; - }; - - // 声明 -#define declareEBPF(eBPFName) struct eBPFName *skel = NULL; - -public: - Scale scale; - - int pid = -1; // 用于设置ebpf程序跟踪的pid - int cpu = -1; // 用于设置ebpf程序跟踪的cpu - int err = 0; // 用于保存错误代码 - - bool ustack = true; // 是否跟踪用户栈 - bool kstack = true; // 是否跟踪内核栈 - uint64_t min = 0; - uint64_t max = __UINT64_MAX__; // 设置采集指标最大值,最小值 - - bool clear = false; // 清除已输出的指标积累量 - int self_pid; - - StackCollector() - { - self_pid = getpid(); - }; - - /// @brief 负责ebpf程序的加载、参数设置和打开操作 - /// @param 无 - /// @return 成功则返回0,否则返回负数 - virtual int load(void) = 0; -#define defaultLoad \ - int load(void) override \ - { \ - StackProgLoadOpen(skel->bss->apid = pid); \ - return 0; \ - }; - - /// @brief 将ebpf程序挂载到跟踪点上 - /// @param 无 - /// @return 成功则返回0,否则返回负数 - virtual int attach(void) = 0; -#define defaultAttach \ - int attach(void) override \ - { \ - err = skel->attach(skel); \ - CHECK_ERR(err, "Failed to attach BPF skeleton"); \ - return 0; \ - }; - - /// @brief 断开ebpf的跟踪点和处理函数间的连接 - /// @param 无 - virtual void detach(void) = 0; -#define defaultDetach \ - void detach(void) override \ - { \ - if (skel) \ - { \ - skel->detach(skel); \ - } \ - }; - - /// @brief 卸载ebpf程序 - /// @param 无 - virtual void unload(void) = 0; -#define defaultUnload \ - void unload(void) override \ - { \ - if (skel) \ - { \ - skel->destroy(skel); \ - } \ - skel = NULL; \ - }; - - operator std::string() - { - std::ostringstream oss; - oss << "Type:" << scale.Type << " Unit:" << scale.Unit << " Period:" << scale.Period << '\n'; - oss << "time:" << getLocalDateTime() << '\n'; - std::map> traces; - oss << "counts:\n"; - { - auto D = sortedCountList(); - if (!D) - return oss.str(); - oss << "pid\tusid\tksid\tcount\n"; - uint64_t trace[MAX_STACKS], *p; - for (auto id : *D) - { - oss << id.pid << '\t' << id.usid << '\t' << id.ksid << '\t' << id.val - << '\n'; - 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--) - ; - for (; p >= trace; p--) - { - 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)) - ; - 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 << (addr - sym.start); - sym.name += ss.str(); - g_symbol_parser.putin_symbol_cache(id.pid, addr, sym.name); - } - else - { - std::stringstream ss(""); - ss << "0x" << std::hex << addr; - sym.name = ss.str(); - g_symbol_parser.putin_symbol_cache(id.pid, addr, sym.name); - } - clearSpace(sym.name); - traces[id.usid].push_back(sym.name); - } - } - if (id.ksid > 0 && traces.find(id.ksid) == traces.end()) - { - bpf_map_lookup_elem(trace_fd, &id.ksid, trace); - for (p = trace + MAX_STACKS - 1; !*p; p--) - ; - for (; p >= trace; p--) - { - uint64_t &addr = *p; - symbol sym; - sym.reset(addr); - if (g_symbol_parser.find_kernel_symbol(sym)) - ; - else - { - std::stringstream ss(""); - ss << "0x" << std::hex << addr; - sym.name = ss.str(); - g_symbol_parser.putin_symbol_cache(pid, addr, sym.name); - } - clearSpace(sym.name); - traces[id.ksid].push_back(sym.name); - } - } - } - delete D; - } - oss << "traces:\n"; - { - oss << "sid\ttrace\n"; - for (auto i : traces) - { - oss << i.first << "\t"; - for (auto s : i.second) - { - oss << s << ';'; - } - oss << "\n"; - } - } - oss << "groups:\n"; - { - if (tgid_fd < 0) - { - return oss.str(); - } - auto keys = new uint32_t[MAX_ENTRIES]; - auto vals = new uint32_t[MAX_ENTRIES]; - uint32_t count = MAX_ENTRIES; - uint32_t next_key; - int err = bpf_map_lookup_batch(tgid_fd, NULL, &next_key, keys, vals, - &count, NULL); - if (err == EFAULT) - { - return oss.str(); - } - oss << "pid\ttgid\n"; - for (uint32_t i = 0; i < count; i++) - { - oss << keys[i] << '\t' << vals[i] << '\n'; - } - delete[] keys; - delete[] vals; - } - oss << "commands:\n"; - { - if (comm_fd < 0) - { - return oss.str(); - } - auto keys = new uint32_t[MAX_ENTRIES]; - auto vals = new char[MAX_ENTRIES][16]; - uint32_t count = MAX_ENTRIES; - uint32_t next_key; - int err = bpf_map_lookup_batch(comm_fd, NULL, &next_key, keys, vals, - &count, NULL); - if (err == EFAULT) - { - return oss.str(); - } - oss << "pid\tcommand\n"; - for (uint32_t i = 0; i < count; i++) - { - oss << keys[i] << '\t' << vals[i] << '\n'; - } - delete[] keys; - delete[] vals; - } - oss << "OK\n"; - return oss.str(); - } -}; - -class OnCPUStackCollector : public StackCollector -{ -private: - declareEBPF(on_cpu_count_bpf); - const char *online_cpus_file = "/sys/devices/system/cpu/online"; - bool *online_mask = NULL; - int *pefds = NULL, num_cpus = 0, num_online_cpus = 0; - struct perf_event_attr attr = {0}; - struct bpf_link **links = NULL; - unsigned long long freq = 49; - -public: - OnCPUStackCollector() - { - setScale(freq); - err = parse_cpu_mask_file(online_cpus_file, &online_mask, &num_online_cpus); - CHECK_ERR_EXIT(err, "Fail to get online CPU numbers"); - num_cpus = libbpf_num_possible_cpus(); - CHECK_ERR_EXIT(num_cpus <= 0, "Fail to get the number of processors"); - }; - - void setScale(uint64_t freq) - { - this->freq = freq; - scale.Period = 1e9 / freq; - scale.Type = "OnCPUTime"; - scale.Unit = "nanoseconds"; - } - - int load(void) override - { - FILE *fp = popen("cat /proc/kallsyms | grep \" avenrun\"", "r"); - CHECK_ERR(!fp, "Failed to draw flame graph"); - unsigned long *load_a; - fscanf(fp, "%p", &load_a); - pclose(fp); - StackProgLoadOpen(skel->bss->load_a = load_a) return 0; - }; - - int attach(void) override - { - attr = { - .type = PERF_TYPE_SOFTWARE, // hardware event can't be used - .size = sizeof(attr), - .config = PERF_COUNT_SW_CPU_CLOCK, - .sample_freq = freq, - .inherit = 1, - .freq = 1, // use freq instead of period - }; - pefds = (int *)malloc(num_cpus * sizeof(int)); - for (int i = 0; i < num_cpus; i++) - { - pefds[i] = -1; - } - links = (struct bpf_link **)calloc(num_cpus, sizeof(struct bpf_link *)); - for (int cpu = 0; cpu < num_cpus; cpu++) - { - /* skip offline/not present CPUs */ - if (cpu >= num_online_cpus || !online_mask[cpu]) - { - continue; - } - /* Set up performance monitoring on a CPU/Core */ - int pefd = perf_event_open(&attr, pid, cpu, -1, 0); - CHECK_ERR(pefd < 0, "Fail to set up performance monitor on a CPU/Core"); - pefds[cpu] = pefd; - /* Attach a BPF program on a CPU */ - links[cpu] = bpf_program__attach_perf_event(skel->progs.do_stack, pefd); // 与内核bpf程序联系 - CHECK_ERR(!links[cpu], "Fail to attach bpf program"); - } - return 0; - } - - void detach(void) override - { - if (links) - { - for (int cpu = 0; cpu < num_cpus; cpu++) - { - - bpf_link__destroy(links[cpu]); - } - free(links); - links = NULL; - } - if (pefds) - { - for (int i = 0; i < num_cpus; i++) - { - if (pefds[i] >= 0) - { - close(pefds[i]); - } - } - free(pefds); - pefds = NULL; - } - } - - defaultUnload; -}; - -class OffCPUStackCollector : public StackCollector -{ -private: - declareEBPF(off_cpu_count_bpf); - -protected: - defaultLoad; - defaultAttach; - defaultDetach; - defaultUnload; - -public: - OffCPUStackCollector() - { - scale.Period = 1 << 20; - scale.Type = "OffCPUTime"; - scale.Unit = "milliseconds"; - }; -}; - -class MemoryStackCollector : public StackCollector -{ -private: - declareEBPF(mem_count_bpf); - -protected: - double data_value(void *d) override - { - return *(uint64_t *)d; - } - -public: - char *object = (char *)"libc.so.6"; - - MemoryStackCollector() - { - count_size = sizeof(uint64_t); - kstack = false; - showDelta = false; - scale.Period = 1; - scale.Type = "LeakedMomery"; - scale.Unit = "bytes"; - }; - - int load(void) override - { - StackProgLoadOpen(); - return 0; - }; - - int attach(void) override - { - ATTACH_UPROBE_CHECKED(skel, malloc, malloc_enter); - ATTACH_URETPROBE_CHECKED(skel, malloc, malloc_exit); - ATTACH_UPROBE_CHECKED(skel, calloc, calloc_enter); - ATTACH_URETPROBE_CHECKED(skel, calloc, calloc_exit); - ATTACH_UPROBE_CHECKED(skel, realloc, realloc_enter); - ATTACH_URETPROBE_CHECKED(skel, realloc, realloc_exit); - ATTACH_UPROBE_CHECKED(skel, free, free_enter); - - ATTACH_UPROBE_CHECKED(skel, mmap, mmap_enter); - ATTACH_URETPROBE_CHECKED(skel, mmap, mmap_exit); - ATTACH_UPROBE_CHECKED(skel, munmap, munmap_enter); - - err = skel->attach(skel); - CHECK_ERR(err, "Failed to attach BPF skeleton"); - return 0; - }; - - void detach(void) override - { - skel->detach(skel); -#define destoryBPFLinkIfExist(name) \ - if (skel->links.name) \ - { \ - bpf_link__destroy(skel->links.name); \ - } - destoryBPFLinkIfExist(malloc_enter); - destoryBPFLinkIfExist(malloc_exit); - destoryBPFLinkIfExist(calloc_enter); - destoryBPFLinkIfExist(calloc_exit); - destoryBPFLinkIfExist(realloc_enter); - destoryBPFLinkIfExist(realloc_exit); - destoryBPFLinkIfExist(free_enter); - destoryBPFLinkIfExist(mmap_enter); - destoryBPFLinkIfExist(mmap_exit); - destoryBPFLinkIfExist(munmap_enter); - }; - - defaultUnload; -}; - -class IOStackCollector : public StackCollector -{ -private: - declareEBPF(io_count_bpf); - -protected: - double data_value(void *data) override - { - io_tuple *p = (io_tuple *)data; - switch (DataType) - { - case AVE: - return 1. * p->size / p->count; - case SIZE: - return p->size; - case COUNT: - return p->count; - default: - return 0; - } - }; - -public: - typedef enum - { - COUNT, - SIZE, - AVE - } io_mod; - - io_mod DataType = io_mod::COUNT; - - void setScale(io_mod mod) - { - DataType = mod; - static const char *Types[] = {"IOCount", "IOSize", "AverageIOSize"}; - static const char *Units[] = {"counts", "bytes", "bytes"}; - scale.Type = Types[mod]; - scale.Unit = Units[mod]; - scale.Period = 1; - }; - - IOStackCollector() - { - count_size = sizeof(io_tuple); - setScale(DataType); - }; - - defaultLoad; - defaultAttach; - defaultDetach; - defaultUnload; -}; - -class ReadaheadStackCollector : public StackCollector -{ -private: - declareEBPF(pre_count_bpf); - -protected: - double data_value(void *data) override - { - ra_tuple *p = (ra_tuple *)data; - return p->expect - p->truth; - }; - -public: - defaultLoad; - defaultAttach; - defaultDetach; - defaultUnload; - - ReadaheadStackCollector() - { - count_size = sizeof(ra_tuple); - showDelta = false; - scale = { - .Type = "UnusedReadaheadPages", - .Unit = "pages", - .Period = 1, - }; - }; -}; - -class StackCountStackCollector : public StackCollector -{ -private: - declareEBPF(stack_count_bpf); - -public: - std::string probe = ""; // 保存命令行的输入 - - StackCountStackCollector() - { - scale = { - .Type = "StackCounts", - .Unit = "Counts", - .Period = 1, - }; - }; - - void setProbe(std::string probe) - { - this->probe = probe; - scale.Type = (probe + scale.Type).c_str(); - } - - defaultLoad; - int attach(void) override - { - skel->links.handle = - bpf_program__attach_kprobe(skel->progs.handle, false, probe.c_str()); - CHECK_ERR(!skel->links.handle, "Fail to attach kprobe"); - return 0; - }; - defaultDetach; - defaultUnload; -}; - -namespace MainConfig -{ - int run_time = __INT_MAX__; // 运行时间 - unsigned delay = 5; // 设置输出间隔 - std::string command = ""; - int32_t target_pid = -1; -} -std::vector StackCollectorList; -void endCollect(void) -{ - signal(SIGINT, SIG_IGN); - for (auto Item : StackCollectorList) - { - if (MainConfig::run_time > 0) - { - std::cout << std::string(*Item) << std::endl; - } - Item->detach(); - Item->unload(); - } - if (MainConfig::command.length()) - { - kill(MainConfig::target_pid, SIGTERM); - } -} - -uint64_t IntTmp; -std::string StrTmp; -int main(int argc, char *argv[]) -{ - auto MainOption = (( - ((clipp::option("-p", "--pid") & clipp::value("pid of sampled process, default -1 for all", MainConfig::target_pid)) % "set pid of process to monitor") | - ((clipp::option("-c", "--command") & clipp::value("to be sampled command to run, default none", MainConfig::command)) % "set command for monitoring the whole life")), - (clipp::option("-d", "--delay") & clipp::value("delay time(seconds) to output, default 5", MainConfig::delay)) % "set the interval to output", - (clipp::option("-t", "--timeout") & clipp::value("run time, default nearly infinite", MainConfig::run_time)) % "set the total simpling time"); - - auto SubOption = (clipp::option("-U", "--user-stack-only").call([] - { StackCollectorList.back()->kstack = false; }) % - "only sample user stacks", - clipp::option("-K", "--kernel-stack-only").call([] - { StackCollectorList.back()->ustack = false; }) % - "only sample kernel stacks", - (clipp::option("-m", "--max-value") & clipp::value("max threshold of sampled value", IntTmp).call([] - { StackCollectorList.back()->max = IntTmp; })) % - "set the max threshold of sampled value", - (clipp::option("-n", "--min-value") & clipp::value("min threshold of sampled value", IntTmp).call([] - { StackCollectorList.back()->min = IntTmp; })) % - "set the min threshold of sampled value"); - - auto OnCpuOption = (clipp::option("on-cpu").call([] - { StackCollectorList.push_back(new OnCPUStackCollector()); }) % - "sample the call stacks of on-cpu processes") & - (clipp::option("-F", "--frequency") & clipp::value("sampling frequency", IntTmp).call([] - { static_cast(StackCollectorList.back())->setScale(IntTmp); }) % - "sampling at a set frequency", - SubOption); - - auto OffCpuOption = clipp::option("off-cpu").call([] - { StackCollectorList.push_back(new OffCPUStackCollector()); }) % - "sample the call stacks of off-cpu processes" & - SubOption; - - auto MemoryOption = clipp::option("mem").call([] - { StackCollectorList.push_back(new MemoryStackCollector()); }) % - "sample the memory usage of call stacks" & - SubOption; - - auto IOOption = clipp::option("io").call([] - { StackCollectorList.push_back(new IOStackCollector()); }) % - "sample the IO data volume of call stacks" & - ((clipp::option("--mod") & (clipp::option("count").call([] - { static_cast(StackCollectorList.back())->setScale(IOStackCollector::io_mod::COUNT); }) % - "Counting the number of I/O operations" | - clipp::option("ave").call([] - { static_cast(StackCollectorList.back())->setScale(IOStackCollector::io_mod::AVE); }) % - "Counting the ave of I/O operations" | - clipp::option("size").call([] - { static_cast(StackCollectorList.back())->setScale(IOStackCollector::io_mod::SIZE); }) % - "Counting the size of I/O operations")) % - "set the statistic mod", - SubOption); - - auto ReadaheadOption = clipp::option("ra").call([] - { StackCollectorList.push_back(new ReadaheadStackCollector()); }) % - "sample the readahead hit rate of call stacks" & - SubOption; - auto StackCountOption = clipp::option("stackcount").call([] - { StackCollectorList.push_back(new StackCountStackCollector()); }) % - "sample the counts of calling stacks" & - (clipp::option("-S", "--String") & clipp::value("probe String", StrTmp).call([] - { static_cast(StackCollectorList.back())->setProbe(StrTmp); }) % - "sampling at a set probe string", - SubOption); - - auto cli = (MainOption, - clipp::option("-v", "--version").call([] - { std::cout << "verion 2.0\n\n"; }) % - "show version", - OnCpuOption, - OffCpuOption, - MemoryOption, - IOOption, - ReadaheadOption, - StackCountOption) % - "statistic call trace relate with some metrics"; - - if (!clipp::parse(argc, argv, cli)) - { - std::cout << clipp::make_man_page(cli, argv[0]) << '\n'; - return 0; - } - - uint64_t eventbuff = 1; - int child_exec_event_fd = eventfd(0, EFD_CLOEXEC); - CHECK_ERR(child_exec_event_fd < 0, "failed to create event fd"); - if (MainConfig::command.length()) - { - MainConfig::target_pid = fork(); - switch (MainConfig::target_pid) - { - case -1: - { - std::cout << "command create failed." << std::endl; - return -1; - } - case 0: - { - const auto bytes = read(child_exec_event_fd, &eventbuff, sizeof(eventbuff)); - CHECK_ERR(bytes < 0, "failed to read from fd %ld", bytes) - else CHECK_ERR(bytes != sizeof(eventbuff), "read unexpected size %ld", bytes); - printf("child exec %s\n", MainConfig::command.c_str()); - CHECK_ERR_EXIT(execl("/bin/bash", "bash", "-c", MainConfig::command.c_str(), NULL), "failed to execute child command"); - break; - } - default: - { - printf("create child %d\n", MainConfig::target_pid); - break; - } - } - } - - for (auto Item = StackCollectorList.begin(); Item != StackCollectorList.end();) - { - (*Item)->pid = MainConfig::target_pid; - if ((*Item)->load()) - { - goto err; - } - if ((*Item)->attach()) - { - goto err; - } - Item++; - continue; - err: - fprintf(stderr, "%s eBPF prog err\n", (*Item)->scale.Type); - (*Item)->detach(); - (*Item)->unload(); - Item = StackCollectorList.erase(Item); - } - - if (MainConfig::command.length()) - { - printf("wake up child\n"); - write(child_exec_event_fd, &eventbuff, sizeof(eventbuff)); - } - - // printf("display mode: %d\n", MainConfig::d_mode); - - for (; MainConfig::run_time > 0 && (MainConfig::target_pid < 0 || !kill(MainConfig::target_pid, 0)); MainConfig::run_time -= MainConfig::delay) - { - sleep(MainConfig::delay); - for (auto Item : StackCollectorList) - { - Item->detach(); - std::cout << std::string(*Item); - Item->attach(); - } - } - - atexit(endCollect); -} \ No newline at end of file diff --git "a/eBPF_Supermarket/Stack_Analyser/libbpf/\346\241\206\346\236\266\344\275\277\347\224\250\346\226\271\346\263\225.md" "b/eBPF_Supermarket/Stack_Analyser/libbpf/\346\241\206\346\236\266\344\275\277\347\224\250\346\226\271\346\263\225.md" deleted file mode 100644 index 4c68a9bb6..000000000 --- "a/eBPF_Supermarket/Stack_Analyser/libbpf/\346\241\206\346\236\266\344\275\277\347\224\250\346\226\271\346\263\225.md" +++ /dev/null @@ -1,31 +0,0 @@ -# eBPF侧 - -1. 在 `bpf/` 文件夹中添加自定义eBPF程序代码,命名方式为 `子功能名.bpf.c` - -2. 在代码中使用 `DECLARE_MAPS(type)` 宏声明公用的map并以 `type` 指定 count 值的类型 - -3. 使用 `KERNEL_STACK` 和 `USER_STACK` 来获取内核和用户调用栈id,调用栈会自动保存在 stack_trace 中 - -# 用户侧 - -1. 在 `include/stack_analyzer.h` 中的 `MOD` 枚举类型定义中新增一个功能模块的标识,将该名称添加到`MOD_NUM`前面即可 - -2. 在 `stack_analyzer.cc` 中创建一个 `bpf_loader` 的子类,在其中重写以下函数: - - 1. 自定义eBPF程序加载函数 `int load(void)` 加载自定义eBPF程序 - - 2. 自定义eBPF程序挂载函数 `int attach(void)` 设置eBPF程序相应参数并挂载到相应跟踪点 - - 3. 遍历 count map ,会使用自定义解析函数 `uint64_t data_value(void *count)` 将count解析为单值value并产生以value值升序的有序的 sortedData(pid, usid, ksid, count) 列表 - - 4. 若不需要实时展示火焰图,则将sortedData列表输出,每条输出会使用自定义注解函数 `std::string data_str(uint64_t value)` 为value值添加对应的单位和名称 - - 5. 自定义eBPF程序卸载函数 `void detach(void)`,将eBPF程序与跟踪点分离,停止采集 - - 6. 自定义eBPF程序清除函数 `void remove(void)`,将eBPF程序清除 - -3. 在 main 函数中添加新增子命令和对应参数解析语句 - -# 编译侧 - -在 `Makefile` 文件中的 `APPS` 变量中添加 新增的子功能名 \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/main.cpp b/eBPF_Supermarket/Stack_Analyser/main.cpp new file mode 100644 index 000000000..e529c5459 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/main.cpp @@ -0,0 +1,200 @@ +#include +#include + +#include "bpf/OnCPUStackCollector.h" +#include "bpf/OffCPUStackCollector.h" +#include "bpf/MemoryStackCollector.h" +#include "bpf/IOStackCollector.h" +#include "bpf/ReadaheadStackCollector.h" +#include "bpf/ProbeStackCollector.h" + +#include "sa_user.h" +#include "clipp.h" + + +namespace MainConfig +{ + int run_time = __INT_MAX__; // 运行时间 + unsigned delay = 5; // 设置输出间隔 + std::string command = ""; + int32_t target_pid = -1; +} + +std::vector StackCollectorList; + +void endCollect(void) +{ + signal(SIGINT, SIG_IGN); + for (auto Item : StackCollectorList) + { + if (MainConfig::run_time > 0) + { + std::cout << std::string(*Item) << std::endl; + } + Item->detach(); + Item->unload(); + } + if (MainConfig::command.length()) + { + kill(MainConfig::target_pid, SIGTERM); + } +} + +uint64_t IntTmp; +std::string StrTmp; + +int main(int argc, char *argv[]) +{ + auto MainOption = (( + ((clipp::option("-p", "--pid") & clipp::value("pid of sampled process, default -1 for all", MainConfig::target_pid)) % "set pid of process to monitor") | + ((clipp::option("-c", "--command") & clipp::value("to be sampled command to run, default none", MainConfig::command)) % "set command for monitoring the whole life")), + (clipp::option("-d", "--delay") & clipp::value("delay time(seconds) to output, default 5", MainConfig::delay)) % "set the interval to output", + (clipp::option("-t", "--timeout") & clipp::value("run time, default nearly infinite", MainConfig::run_time)) % "set the total simpling time"); + + auto SubOption = (clipp::option("-U", "--user-stack-only").call([] + { StackCollectorList.back()->kstack = false; }) % + "only sample user stacks", + clipp::option("-K", "--kernel-stack-only").call([] + { StackCollectorList.back()->ustack = false; }) % + "only sample kernel stacks", + (clipp::option("-m", "--max-value") & clipp::value("max threshold of sampled value", IntTmp).call([] + { StackCollectorList.back()->max = IntTmp; })) % + "set the max threshold of sampled value", + (clipp::option("-n", "--min-value") & clipp::value("min threshold of sampled value", IntTmp).call([] + { StackCollectorList.back()->min = IntTmp; })) % + "set the min threshold of sampled value"); + + auto OnCpuOption = (clipp::option("on-cpu").call([] + { StackCollectorList.push_back(new OnCPUStackCollector()); }) % + "sample the call stacks of on-cpu processes") & + (clipp::option("-F", "--frequency") & clipp::value("sampling frequency", IntTmp).call([] + { static_cast(StackCollectorList.back())->setScale(IntTmp); }) % + "sampling at a set frequency", + SubOption); + + auto OffCpuOption = clipp::option("off-cpu").call([] + { StackCollectorList.push_back(new OffCPUStackCollector()); }) % + "sample the call stacks of off-cpu processes" & + SubOption; + + auto MemoryOption = clipp::option("mem").call([] + { StackCollectorList.push_back(new MemoryStackCollector()); }) % + "sample the memory usage of call stacks" & + SubOption; + + auto IOOption = clipp::option("io").call([] + { StackCollectorList.push_back(new IOStackCollector()); }) % + "sample the IO data volume of call stacks" & + ((clipp::option("--mod") & (clipp::option("count").call([] + { static_cast(StackCollectorList.back())->setScale(IOStackCollector::io_mod::COUNT); }) % + "Counting the number of I/O operations" | + clipp::option("ave").call([] + { static_cast(StackCollectorList.back())->setScale(IOStackCollector::io_mod::AVE); }) % + "Counting the ave of I/O operations" | + clipp::option("size").call([] + { static_cast(StackCollectorList.back())->setScale(IOStackCollector::io_mod::SIZE); }) % + "Counting the size of I/O operations")) % + "set the statistic mod", + SubOption); + + auto ReadaheadOption = clipp::option("ra").call([] + { StackCollectorList.push_back(new ReadaheadStackCollector()); }) % + "sample the readahead hit rate of call stacks" & + SubOption; + auto StackCountOption = clipp::option("stackcount").call([] + { StackCollectorList.push_back(new StackCountStackCollector()); }) % + "sample the counts of calling stacks" & + (clipp::option("-S", "--String") & clipp::value("probe String", StrTmp).call([] + { static_cast(StackCollectorList.back())->setScale(StrTmp); }) % + "sampling at a set probe string", + SubOption); + + auto cli = (MainOption, + clipp::option("-v", "--version").call([] + { std::cout << "verion 2.0\n\n"; }) % + "show version", + OnCpuOption, + OffCpuOption, + MemoryOption, + IOOption, + ReadaheadOption, + StackCountOption) % + "statistic call trace relate with some metrics"; + + if (!clipp::parse(argc, argv, cli)) + { + std::cout << clipp::make_man_page(cli, argv[0]) << '\n'; + return 0; + } + + uint64_t eventbuff = 1; + int child_exec_event_fd = eventfd(0, EFD_CLOEXEC); + CHECK_ERR(child_exec_event_fd < 0, "failed to create event fd"); + if (MainConfig::command.length()) + { + MainConfig::target_pid = fork(); + switch (MainConfig::target_pid) + { + case -1: + { + std::cout << "command create failed." << std::endl; + return -1; + } + case 0: + { + const auto bytes = read(child_exec_event_fd, &eventbuff, sizeof(eventbuff)); + CHECK_ERR(bytes < 0, "failed to read from fd %ld", bytes) + else CHECK_ERR(bytes != sizeof(eventbuff), "read unexpected size %ld", bytes); + printf("child exec %s\n", MainConfig::command.c_str()); + CHECK_ERR_EXIT(execl("/bin/bash", "bash", "-c", MainConfig::command.c_str(), NULL), "failed to execute child command"); + break; + } + default: + { + printf("create child %d\n", MainConfig::target_pid); + break; + } + } + } + + for (auto Item = StackCollectorList.begin(); Item != StackCollectorList.end();) + { + (*Item)->pid = MainConfig::target_pid; + if ((*Item)->load()) + { + goto err; + } + if ((*Item)->attach()) + { + goto err; + } + Item++; + continue; + err: + fprintf(stderr, "%s eBPF prog err\n", (*Item)->scale.Type); + (*Item)->detach(); + (*Item)->unload(); + Item = StackCollectorList.erase(Item); + } + + if (MainConfig::command.length()) + { + printf("wake up child\n"); + write(child_exec_event_fd, &eventbuff, sizeof(eventbuff)); + } + + // printf("display mode: %d\n", MainConfig::d_mode); + + for (; MainConfig::run_time > 0 && (MainConfig::target_pid < 0 || !kill(MainConfig::target_pid, 0)); MainConfig::run_time -= MainConfig::delay) + { + sleep(MainConfig::delay); + for (auto Item : StackCollectorList) + { + Item->detach(); + std::cout << std::string(*Item); + Item->attach(); + } + } + + atexit(endCollect); +} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/IOStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/IOStackCollector.cpp new file mode 100644 index 000000000..5160adf42 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf/IOStackCollector.cpp @@ -0,0 +1,55 @@ + +#include "bpf/IOStackCollector.h" + +double IOStackCollector::count_value(void *data) +{ + io_tuple *p = (io_tuple *)data; + switch (DataType) + { + case AVE: + return 1. * p->size / p->count; + case SIZE: + return p->size; + case COUNT: + return p->count; + default: + return 0; + } +}; + +void IOStackCollector::setScale(io_mod mod) +{ + DataType = mod; + static const char *Types[] = {"IOCount", "IOSize", "AverageIOSize"}; + static const char *Units[] = {"counts", "bytes", "bytes"}; + scale.Type = Types[mod]; + scale.Unit = Units[mod]; + scale.Period = 1; +}; + +IOStackCollector::IOStackCollector() +{ + setScale(DataType); +}; + +int IOStackCollector::load(void) +{ + StackProgLoadOpen(); + return 0; +} + +int IOStackCollector::attach(void) +{ + defaultAttach; + return 0; +} + +void IOStackCollector::detach(void) +{ + defaultDetach; +} + +void IOStackCollector::unload(void) +{ + defaultUnload; +} diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/MemoryStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/MemoryStackCollector.cpp new file mode 100644 index 000000000..93e204365 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf/MemoryStackCollector.cpp @@ -0,0 +1,66 @@ +#include "bpf/MemoryStackCollector.h" + +double MemoryStackCollector::count_value(void *d) +{ + return *(uint64_t *)d; +} + +MemoryStackCollector::MemoryStackCollector() +{ + kstack = false; + showDelta = false; + scale.Period = 1; + scale.Type = "LeakedMomery"; + scale.Unit = "bytes"; +}; + +int MemoryStackCollector::load(void) +{ + StackProgLoadOpen(); + return 0; +}; + +int MemoryStackCollector::attach(void) +{ + at_ent(skel, malloc, malloc_enter); + at_ret(skel, malloc, malloc_exit); + at_ent(skel, calloc, calloc_enter); + at_ret(skel, calloc, calloc_exit); + at_ent(skel, realloc, realloc_enter); + at_ret(skel, realloc, realloc_exit); + at_ent(skel, free, free_enter); + + at_ent(skel, mmap, mmap_enter); + at_ret(skel, mmap, mmap_exit); + at_ent(skel, munmap, munmap_enter); + + err = skel->attach(skel); + CHECK_ERR(err, "Failed to attach BPF skeleton"); + return 0; +}; + +void MemoryStackCollector::detach(void) +{ + skel->detach(skel); +#define des(name) \ + if (skel->links.name) \ + { \ + bpf_link__destroy(skel->links.name); \ + } + + des(malloc_enter); + des(malloc_exit); + des(calloc_enter); + des(calloc_exit); + des(realloc_enter); + des(realloc_exit); + des(free_enter); + des(mmap_enter); + des(mmap_exit); + des(munmap_enter); +}; + +void MemoryStackCollector::unload(void) +{ + defaultUnload; +} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/OffCPUStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/OffCPUStackCollector.cpp new file mode 100644 index 000000000..b3c9864f9 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf/OffCPUStackCollector.cpp @@ -0,0 +1,33 @@ +#include "bpf/OffCPUStackCollector.h" + +OffCPUStackCollector::OffCPUStackCollector() +{ + scale.Period = 1 << 20; + scale.Type = "OffCPUTime"; + scale.Unit = "milliseconds"; +}; + +double OffCPUStackCollector::count_value(void *data) +{ + return *(uint32_t *)data; +}; + +int OffCPUStackCollector::load(void) +{ + StackProgLoadOpen(skel->bss->apid = pid;); + return 0; +} + +int OffCPUStackCollector::attach(void) +{ + defaultAttach; + return 0; +} + +void OffCPUStackCollector::detach(void) { + defaultDetach; +} + +void OffCPUStackCollector::unload(void) { + defaultUnload; +} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/OnCPUStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/OnCPUStackCollector.cpp new file mode 100644 index 000000000..a883a7045 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf/OnCPUStackCollector.cpp @@ -0,0 +1,124 @@ +#include "bpf/OnCPUStackCollector.h" +#include +#include + +/// @brief staring perf event +/// @param hw_event attribution of the perf event +/// @param pid the pid to track. 0 for the calling process. -1 for all processes. +/// @param cpu the cpu to track. -1 for all cpu +/// @param group_fd fd of event group leader +/// @param flags setting +/// @return fd of perf event +static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, + unsigned long flags) +{ + return syscall(SYS_perf_event_open, hw_event, pid, cpu, group_fd, flags); +} + +extern "C" +{ + extern int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz); +} + +OnCPUStackCollector::OnCPUStackCollector() +{ + setScale(freq); +}; + +void OnCPUStackCollector::setScale(uint64_t freq) +{ + this->freq = freq; + scale.Period = 1e9 / freq; + scale.Type = "OnCPUTime"; + scale.Unit = "nanoseconds"; +} + +double OnCPUStackCollector::count_value(void *data) +{ + return *(uint32_t *)data; +}; + +int OnCPUStackCollector::load(void) +{ + FILE *fp = popen("cat /proc/kallsyms | grep \" avenrun\"", "r"); + CHECK_ERR(!fp, "Failed to draw flame graph"); + unsigned long *load_a; + fscanf(fp, "%p", &load_a); + pclose(fp); + StackProgLoadOpen(skel->bss->load_a = load_a;); + + return 0; +}; + +int OnCPUStackCollector::attach(void) +{ + const char *online_cpus_file = "/sys/devices/system/cpu/online"; + bool *online_mask; + int num_online_cpus; + err = parse_cpu_mask_file(online_cpus_file, &online_mask, &num_online_cpus); + CHECK_ERR(err, "Fail to get online CPU numbers"); + + num_cpus = libbpf_num_possible_cpus(); + CHECK_ERR(num_cpus <= 0, "Fail to get the number of processors"); + + struct perf_event_attr attr = { + .type = PERF_TYPE_SOFTWARE, // hardware event can't be used + .size = sizeof(attr), + .config = PERF_COUNT_SW_CPU_CLOCK, + .sample_freq = freq, + .inherit = 1, + .freq = 1, // use freq instead of period + }; + pefds = (int *)malloc(num_cpus * sizeof(int)); + for (int i = 0; i < num_cpus; i++) + { + pefds[i] = -1; + } + links = (struct bpf_link **)calloc(num_cpus, sizeof(struct bpf_link *)); + for (int cpu = 0; cpu < num_cpus; cpu++) + { + /* skip offline/not present CPUs */ + if (cpu >= num_online_cpus || !online_mask[cpu]) + { + continue; + } + /* Set up performance monitoring on a CPU/Core */ + int pefd = perf_event_open(&attr, pid, cpu, -1, 0); + CHECK_ERR(pefd < 0, "Fail to set up performance monitor on a CPU/Core"); + pefds[cpu] = pefd; + /* Attach a BPF program on a CPU */ + links[cpu] = bpf_program__attach_perf_event(skel->progs.do_stack, pefd); // 与内核bpf程序联系 + CHECK_ERR(!links[cpu], "Fail to attach bpf program"); + } + return 0; +} + +void OnCPUStackCollector::detach(void) +{ + if (links) + { + for (int cpu = 0; cpu < num_cpus; cpu++) + { + bpf_link__destroy(links[cpu]); + } + free(links); + links = NULL; + } + if (pefds) + { + for (int i = 0; i < num_cpus; i++) + { + if (pefds[i] >= 0) + { + close(pefds[i]); + } + } + free(pefds); + pefds = NULL; + } +}; + +void OnCPUStackCollector::unload(void) +{ + defaultUnload; +}; diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/ProbeStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/ProbeStackCollector.cpp new file mode 100644 index 000000000..3c69c5af1 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf/ProbeStackCollector.cpp @@ -0,0 +1,44 @@ +#include "bpf/ProbeStackCollector.h" + +double StackCountStackCollector::count_value(void *data) { + return *(uint32_t*)data; +} + +StackCountStackCollector::StackCountStackCollector() +{ + scale = { + .Type = "StackCounts", + .Unit = "Counts", + .Period = 1, + }; +}; + +void StackCountStackCollector::setScale(std::string probe) +{ + this->probe = probe; + scale.Type = (probe + scale.Type).c_str(); +}; + +int StackCountStackCollector::load(void) +{ + StackProgLoadOpen(); + return 0; +}; + +int StackCountStackCollector::attach(void) +{ + skel->links.handle = + bpf_program__attach_kprobe(skel->progs.handle, false, probe.c_str()); + CHECK_ERR(!skel->links.handle, "Fail to attach kprobe"); + return 0; +}; + +void StackCountStackCollector::detach(void) +{ + defaultDetach; +}; + +void StackCountStackCollector::unload(void) +{ + defaultUnload; +}; diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/ReadaheadStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/ReadaheadStackCollector.cpp new file mode 100644 index 000000000..e4b292658 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf/ReadaheadStackCollector.cpp @@ -0,0 +1,39 @@ +#include "bpf/ReadaheadStackCollector.h" + +double ReadaheadStackCollector::count_value(void *data) +{ + ra_tuple *p = (ra_tuple *)data; + return p->expect - p->truth; +}; + +ReadaheadStackCollector::ReadaheadStackCollector() +{ + showDelta = false; + scale = { + .Type = "UnusedReadaheadPages", + .Unit = "pages", + .Period = 1, + }; +}; + +int ReadaheadStackCollector::load(void) +{ + StackProgLoadOpen(); + return 0; +} + +int ReadaheadStackCollector::attach(void) +{ + defaultAttach; + return 0; +} + +void ReadaheadStackCollector::detach(void) +{ + defaultDetach; +} + +void ReadaheadStackCollector::unload(void) +{ + defaultUnload; +} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/TemplateClass.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/TemplateClass.cpp new file mode 100644 index 000000000..12a60eaf1 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf/TemplateClass.cpp @@ -0,0 +1,26 @@ +#include "bpf/TemplateClass.h" + +// ========== implement virtual func ========== + +double TemplateClass::count_value(void *data) +{ + return *(uint32_t*)data; +}; + +int TemplateClass::load(void) +{ + return 0; +}; + +int TemplateClass::attach(void) +{ + return 0; +}; + +void TemplateClass::detach(void){}; + +void TemplateClass::unload(void){}; + +// ========== other implementations ========== + +TemplateClass::TemplateClass(){}; \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/eBPFStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/eBPFStackCollector.cpp new file mode 100644 index 000000000..b73c07f5a --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf/eBPFStackCollector.cpp @@ -0,0 +1,218 @@ +#include "bpf/eBPFStackCollector.h" +#include "sa_user.h" +#include "symbol.h" + +#include +#include +#include +#include + +std::string getLocalDateTime(void) +{ + auto t = time(NULL); + auto localTm = localtime(&t); + char buff[32]; + strftime(buff, 32, "%Y%m%d_%H_%M_%S", localTm); + return std::string(buff); +}; + +bool operator<(const CountItem a, const CountItem b) +{ + if (a.v < b.v || (a.v == b.v && a.k.pid < b.k.pid)) + return true; + else + return false; +} + +StackCollector::StackCollector() +{ + self_pid = getpid(); +}; + +std::vector *StackCollector::sortedCountList(void) +{ + auto psid_count = bpf_object__find_map_by_name(obj, "psid_count"); + auto val_size = bpf_map__value_size(psid_count); + auto value_fd = bpf_object__find_map_fd_by_name(obj, "psid_count"); + + auto keys = new psid[MAX_ENTRIES]; + auto vals = new char[MAX_ENTRIES * val_size]; + uint32_t count = MAX_ENTRIES; + psid next_key; + int err; + if (showDelta) + { + err = bpf_map_lookup_and_delete_batch(value_fd, NULL, &next_key, keys, vals, &count, NULL); + } + else + { + err = bpf_map_lookup_batch(value_fd, NULL, &next_key, keys, vals, &count, NULL); + } + if (err == EFAULT) + { + return NULL; + } + + auto D = new std::vector(); + for (uint32_t i = 0; i < count; i++) + { + CountItem d(keys[i], count_value(vals + val_size * i)); + D->insert(std::lower_bound(D->begin(), D->end(), d), d); + } + delete[] keys; + delete[] vals; + return D; +}; + +StackCollector::operator std::string() +{ + std::ostringstream oss; + oss << "Type:" << scale.Type << " Unit:" << scale.Unit << " Period:" << scale.Period << '\n'; + oss << "time:" << getLocalDateTime() << '\n'; + std::map> traces; + + oss << "counts:\n"; + { + auto D = sortedCountList(); + if (!D) + return oss.str(); + oss << "pid\tusid\tksid\tcount\n"; + uint64_t trace[MAX_STACKS], *p; + for (auto i : *D) + { + auto &id = i.k; + auto &v = i.v; + auto trace_fd = bpf_object__find_map_fd_by_name(obj, "stack_trace"); + oss << id.pid << '\t' << id.usid << '\t' << id.ksid << '\t' << v << '\n'; + 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--) + ; + for (; p >= trace; p--) + { + 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)) + ; + 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 << (addr - sym.start); + sym.name += ss.str(); + g_symbol_parser.putin_symbol_cache(id.pid, addr, sym.name); + } + else + { + std::stringstream ss(""); + ss << "0x" << std::hex << addr; + sym.name = ss.str(); + g_symbol_parser.putin_symbol_cache(id.pid, addr, sym.name); + } + clearSpace(sym.name); + traces[id.usid].push_back(sym.name); + } + } + if (id.ksid > 0 && traces.find(id.ksid) == traces.end()) + { + bpf_map_lookup_elem(trace_fd, &id.ksid, trace); + for (p = trace + MAX_STACKS - 1; !*p; p--) + ; + for (; p >= trace; p--) + { + uint64_t &addr = *p; + symbol sym; + sym.reset(addr); + if (g_symbol_parser.find_kernel_symbol(sym)) + ; + else + { + std::stringstream ss(""); + ss << "0x" << std::hex << addr; + sym.name = ss.str(); + g_symbol_parser.putin_symbol_cache(pid, addr, sym.name); + } + clearSpace(sym.name); + traces[id.ksid].push_back(sym.name); + } + } + } + delete D; + } + + oss << "traces:\n"; + { + oss << "sid\ttrace\n"; + for (auto i : traces) + { + oss << i.first << "\t"; + for (auto s : i.second) + { + oss << s << ';'; + } + oss << "\n"; + } + } + + oss << "groups:\n"; + { + auto tgid_fd = bpf_object__find_map_fd_by_name(obj, "pid_tgid"); + if (tgid_fd < 0) + { + return oss.str(); + } + auto keys = new uint32_t[MAX_ENTRIES]; + auto vals = new uint32_t[MAX_ENTRIES]; + uint32_t count = MAX_ENTRIES; + uint32_t next_key; + int err = bpf_map_lookup_batch(tgid_fd, NULL, &next_key, keys, vals, + &count, NULL); + if (err == EFAULT) + { + return oss.str(); + } + oss << "pid\ttgid\n"; + for (uint32_t i = 0; i < count; i++) + { + oss << keys[i] << '\t' << vals[i] << '\n'; + } + delete[] keys; + delete[] vals; + } + + oss << "commands:\n"; + { + auto comm_fd = bpf_object__find_map_fd_by_name(obj, "pid_comm"); + if (comm_fd < 0) + { + return oss.str(); + } + auto keys = new uint32_t[MAX_ENTRIES]; + auto vals = new char[MAX_ENTRIES][16]; + uint32_t count = MAX_ENTRIES; + uint32_t next_key; + int err = bpf_map_lookup_batch(comm_fd, NULL, &next_key, keys, vals, + &count, NULL); + if (err == EFAULT) + { + return oss.str(); + } + oss << "pid\tcommand\n"; + for (uint32_t i = 0; i < count; i++) + { + oss << keys[i] << '\t' << vals[i] << '\n'; + } + delete[] keys; + delete[] vals; + } + + oss << "OK\n"; + return oss.str(); +} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/bpf/io_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/src/bpf/io_count.bpf.c similarity index 56% rename from eBPF_Supermarket/Stack_Analyser/libbpf/bpf/io_count.bpf.c rename to eBPF_Supermarket/Stack_Analyser/src/bpf/io_count.bpf.c index 774fd1a9a..fa6d1ccb4 100644 --- a/eBPF_Supermarket/Stack_Analyser/libbpf/bpf/io_count.bpf.c +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf/io_count.bpf.c @@ -22,6 +22,7 @@ #include #include "sa_ebpf.h" +#include "bpf/IOStackCollector.h" #include "task.h" DeclareCommonMaps(io_tuple); @@ -30,20 +31,20 @@ int apid = 0; const char LICENSE[] SEC("license") = "GPL"; -static int do_stack(struct trace_event_raw_sys_enter *ctx) +static int do_stack(struct trace_event_raw_sys_enter* ctx) { - struct task_struct *curr = (struct task_struct *)bpf_get_current_task(); // 利用bpf_get_current_task()获得当前的进程tsk + struct task_struct* curr = (struct task_struct*)bpf_get_current_task(); //利用bpf_get_current_task()获得当前的进程tsk ignoreKthread(curr); - u32 pid = get_task_ns_pid(curr); // 利用帮助函数获得当前进程的pid + u32 pid = get_task_ns_pid(curr); //利用帮助函数获得当前进程的pid if ((apid >= 0 && pid != apid) || !pid || pid == self_pid) return 0; - u64 len = BPF_CORE_READ(ctx, args[2]); // 读取IO类系统调用的第三个参数,都表示数据大小 + u64 len = BPF_CORE_READ(ctx, args[2]); // 读取系统调用的第三个参数 if (len <= min || len > max) return 0; - u32 tgid = get_task_ns_tgid(curr); // 利用帮助函数获取进程的tgid - bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); // 将pid_tgid表中的pid选项更新为tgid,若没有该表项,则创建 - comm *p = bpf_map_lookup_elem(&pid_comm, &pid); // p指向pid_comm哈希表中的pid表项对应的value - if (!p) // 如果p不为空,获取当前进程名保存至name中,如果pid_comm当中不存在pid name项,则更新 + u32 tgid = get_task_ns_tgid(curr); //利用帮助函数获取进程的tgid + bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); //将pid_tgid表中的pid选项更新为tgid,若没有该表项,则创建 + comm* p = bpf_map_lookup_elem(&pid_comm, &pid); //p指向pid_comm哈希表中的pid表项对应的value + if (!p) //如果p不为空,获取当前进程名保存至name中,如果pid_comm当中不存在pid name项,则更新 { comm name; bpf_get_current_comm(&name, COMM_LEN); @@ -51,27 +52,25 @@ static int do_stack(struct trace_event_raw_sys_enter *ctx) } psid apsid = { .pid = pid, - .usid = u ? USER_STACK : -1, // u存在,则USER_STACK - .ksid = k ? KERNEL_STACK : -1, // K存在,则KERNEL_STACK + .usid = u ? USER_STACK : -1, //u存在,则USER_STACK + .ksid = k ? KERNEL_STACK : -1, //K存在,则KERNEL_STACK }; // record time delta - io_tuple *d = bpf_map_lookup_elem(&psid_count, &apsid); // count指向psid_count表当中的apsid表项,即size + io_tuple* d = bpf_map_lookup_elem(&psid_count, &apsid); //count指向psid_count表当中的apsid表项,即size - if (!d) - { - io_tuple nd = {.count = 1, .size = len}; + if (!d) { + io_tuple nd = { .count = 1, .size = len }; bpf_map_update_elem(&psid_count, &apsid, &nd, BPF_NOEXIST); } - else - { + else { d->count++; d->size += len; } return 0; } -#define io_sec_tp(name) \ +#define io_sec_tp(name) \ SEC("tp/syscalls/sys_enter_" #name) \ int prog_t_##name(struct trace_event_raw_sys_enter *ctx) { return do_stack(ctx); } @@ -84,11 +83,12 @@ io_sec_tp(sendto); // tracepoint:syscalls:sys_enter_poll // tracepoint:syscalls:sys_enter_epoll_wait + // 1. 设置挂载点 // tracepoint/syscalls/sys_enter_write 读操作 // tracepoint/syscalls/sys_enter_read 写操作 // tracepoint/syscalls/sys_enter_recvfrom 接收数据 // tracepoint/syscalls/sys_enter_sendto 发送数据 -// 2. 执行程序 int prog_t_##name(struct trace_event_raw_sys_enter *ctx) { return do_stack(ctx); } -// 最终调用上面的do_stack函数 \ No newline at end of file +//2. 执行程序 int prog_t_##name(struct trace_event_raw_sys_enter *ctx) { return do_stack(ctx); } +//最终调用上面的do_stack函数 \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/bpf/mem_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/src/bpf/mem_count.bpf.c similarity index 100% rename from eBPF_Supermarket/Stack_Analyser/libbpf/bpf/mem_count.bpf.c rename to eBPF_Supermarket/Stack_Analyser/src/bpf/mem_count.bpf.c diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/bpf/off_cpu_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/src/bpf/off_cpu_count.bpf.c similarity index 100% rename from eBPF_Supermarket/Stack_Analyser/libbpf/bpf/off_cpu_count.bpf.c rename to eBPF_Supermarket/Stack_Analyser/src/bpf/off_cpu_count.bpf.c diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/bpf/on_cpu_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/src/bpf/on_cpu_count.bpf.c similarity index 100% rename from eBPF_Supermarket/Stack_Analyser/libbpf/bpf/on_cpu_count.bpf.c rename to eBPF_Supermarket/Stack_Analyser/src/bpf/on_cpu_count.bpf.c diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/pre_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/src/bpf/pre_count.bpf.c new file mode 100644 index 000000000..6d5e95581 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf/pre_count.bpf.c @@ -0,0 +1,131 @@ +// Copyright 2023 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// 内核态bpf的预读取分析模块代码 + +#include "vmlinux.h" +#include +#include +#include + +#include "sa_ebpf.h" +#include "task.h" +#include "bpf/ReadaheadStackCollector.h" + +#define MINBLOCK_US 1ULL +#define MAXBLOCK_US 99999999ULL + +DeclareCommonMaps(ra_tuple); +DeclareCommonVar(); + +int apid = 0; +BPF_HASH(in_ra, u32, psid); +BPF_HASH(page_psid, struct page *, psid); + +SEC("fentry/page_cache_ra_unbounded") // fentry在内核函数page_cache_ra_unbounded进入时触发的挂载点 +int BPF_PROG(page_cache_ra_unbounded) +{ + struct task_struct *curr = (struct task_struct *)bpf_get_current_task(); + ignoreKthread(curr); + u32 pid = get_task_ns_pid(curr); // 获取当前进程tgid,用户空间的pid即是tgid + + if ((apid >= 0 && pid != apid) || !pid || pid == self_pid) + return 0; + + u32 tgid = get_task_ns_tgid(curr); + bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); // 更新pid_tgid表中的pid对应的值 + comm *p = bpf_map_lookup_elem(&pid_comm, &pid); // p指向pid_comm表中pid对应的值 + if (!p) + { + comm name; + bpf_get_current_comm(&name, COMM_LEN); // 获取当前进程名 + bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST); // 在pid_comm表中更新pid对应的值 + } + + psid apsid = { + .pid = pid, + .usid = u ? USER_STACK : -1, + .ksid = k ? KERNEL_STACK : -1, + }; + + ra_tuple *d = bpf_map_lookup_elem(&psid_count, &apsid); // d指向psid_count表中的apsid对应的类型为tuple的值 + if (!d) + { + ra_tuple a = {.expect = 0, .truth = 0}; // 初始化为0 + bpf_map_update_elem(&psid_count, &apsid, &a, BPF_ANY); // 更新psid_count表中的apsid的值为a + } + bpf_map_update_elem(&in_ra, &pid, &apsid, BPF_ANY); // 更新in_ra表中的pid对应的值为apsid + return 0; +} + +SEC("fexit/alloc_pages") // fexit在内核函数alloc_pages退出时触发,挂载点为alloc_pages +int BPF_PROG(filemap_alloc_folio_ret, gfp_t gfp, unsigned int order, u64 ret) +{ + u32 pid = bpf_get_current_pid_tgid() >> 32; // pid为当前进程的pid + + if ((apid >= 0 && pid != apid) || !pid) + return 0; + + struct psid *apsid = bpf_map_lookup_elem(&in_ra, &pid); // apsid指向了当前in_ra中pid的表项内容 + if (!apsid) + return 0; + + ra_tuple *a = bpf_map_lookup_elem(&psid_count, apsid); // a是指向psid_count的apsid对应的内容 + if (!a) + return 0; + + const u32 lim = 1ul << order; // 1 为长整型,左移order位,即2^order 即申请页的大小 + a->expect += lim; // a->expect+=页大小(未访问) + u64 addr; + bpf_core_read(&addr, sizeof(u64), &ret); // alloc_pages返回的值,即申请页的起始地址保存在addr中 + for (int i = 0; i < lim && i < 1024; i++, addr += 0x1000) + bpf_map_update_elem(&page_psid, &addr, apsid, BPF_ANY); // 更新page_psid表中的addr(从页的起始地址开始到页的结束地址)所对应的值为apsid + + return 0; +} + +SEC("fexit/page_cache_ra_unbounded") +int BPF_PROG(page_cache_ra_unbounded_ret) // fexit在内核函数page_cache_ra_unbounded退出时触发的挂载点 +{ + u32 pid = bpf_get_current_pid_tgid() >> 32; // 获取当前进程的pid + + if ((apid >= 0 && pid != apid) || !pid) + return 0; + + bpf_map_delete_elem(&in_ra, &pid); // 删除了in_ra对应的pid的表项,即删除对应的栈计数信息 + return 0; +} + +SEC("fentry/mark_page_accessed") // fentry在内核函数/mark_page_accessed进入时触发的挂载点,用于标记页面(page)已经被访问 +int BPF_PROG(mark_page_accessed, u64 page) +{ + u32 pid = bpf_get_current_pid_tgid() >> 32; // 获取当前进程的pid + + if ((apid >= 0 && pid != apid) || !pid) + return 0; + psid *apsid; + apsid = bpf_map_lookup_elem(&page_psid, &page); // 查看page_psid对应的 地址page 对应类型为psid的值,并保存在apsid + if (!apsid) + return 0; + ra_tuple *a = bpf_map_lookup_elem(&psid_count, apsid); // a指向psid_count的apsid的内容 + if (!a) + return 0; + a->truth++; // 已访问 + bpf_map_delete_elem(&page_psid, &page); // 删除page_psid的page对应的内容 + return 0; +} + +const char LICENSE[] SEC("license") = "GPL"; \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/bpf/stack_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/src/bpf/stack_count.bpf.c similarity index 100% rename from eBPF_Supermarket/Stack_Analyser/libbpf/bpf/stack_count.bpf.c rename to eBPF_Supermarket/Stack_Analyser/src/bpf/stack_count.bpf.c diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/template.bpf.c b/eBPF_Supermarket/Stack_Analyser/src/bpf/template.bpf.c new file mode 100644 index 000000000..6e6b93a9d --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf/template.bpf.c @@ -0,0 +1,14 @@ + +#include "vmlinux.h" +#include +#include +#include + +#include "sa_ebpf.h" +#include "bpf/TemplateClass.h" +#include "task.h" + +DeclareCommonMaps(__u32); +DeclareCommonVar(); + +const char LICENSE[] SEC("license") = "GPL"; \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/include/elf.cc b/eBPF_Supermarket/Stack_Analyser/src/elf.cc similarity index 81% rename from eBPF_Supermarket/Stack_Analyser/libbpf/include/elf.cc rename to eBPF_Supermarket/Stack_Analyser/src/elf.cc index b846bea45..40831786d 100644 --- a/eBPF_Supermarket/Stack_Analyser/libbpf/include/elf.cc +++ b/eBPF_Supermarket/Stack_Analyser/src/elf.cc @@ -6,23 +6,22 @@ * License terms: GNU General Public License (GPL) version 3 * */ - +#include #include #include #include -#include #include #include #include #include #include -#include -#include "elf.h" +#include "elf.hpp" #define NOTE_ALIGN(n) (((n) + 3) & -4U) -struct sym_section_ctx { +struct sym_section_ctx +{ Elf_Data *syms; Elf_Data *symstrs; Elf_Data *rel_data; @@ -34,26 +33,30 @@ struct sym_section_ctx { unsigned long plt_entsize; }; -struct symbol_sections_ctx { +struct symbol_sections_ctx +{ sym_section_ctx symtab; sym_section_ctx symtab_in_dynsym; sym_section_ctx dynsymtab; }; -struct section_info { +struct section_info +{ Elf_Scn *sec; GElf_Shdr *hdr; }; -struct plt_ctx { +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) { + GElf_Shdr *shp, const char *name, + size_t *idx) +{ Elf_Scn *sec = NULL; size_t cnt = 1; @@ -61,13 +64,15 @@ __attribute__((unused)) static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL)) return NULL; - while ((sec = elf_nextscn(elf, sec)) != 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 (!strcmp(name, str)) + { if (idx) *idx = cnt; @@ -80,7 +85,8 @@ __attribute__((unused)) static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr return sec; } -__attribute__((unused)) static int elf_read_build_id(Elf *elf, char *bf, size_t size) { +__attribute__((unused)) static int elf_read_build_id(Elf *elf, char *bf, size_t size) +{ int err = -1; GElf_Ehdr ehdr; GElf_Shdr shdr; @@ -97,7 +103,8 @@ __attribute__((unused)) static int elf_read_build_id(Elf *elf, char *bf, size_t if (ek != ELF_K_ELF) goto out; - if (gelf_getehdr(elf, &ehdr) == NULL) { + if (gelf_getehdr(elf, &ehdr) == NULL) + { fprintf(stderr, "%s: cannot get elf header.\n", __func__); goto out; } @@ -108,7 +115,8 @@ __attribute__((unused)) static int elf_read_build_id(Elf *elf, char *bf, size_t * '.notes' * '.note' (VDSO specific) */ - do { + do + { sec = elf_section_by_name(elf, &ehdr, &shdr, ".note.gnu.build-id", NULL); @@ -138,7 +146,8 @@ __attribute__((unused)) static int elf_read_build_id(Elf *elf, char *bf, size_t ptr = (char *)data->d_buf; - while ((intptr_t)ptr < (intptr_t)((char *)data->d_buf + data->d_size)) { + 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); @@ -149,8 +158,10 @@ __attribute__((unused)) static int elf_read_build_id(Elf *elf, char *bf, size_t ptr += namesz; if (nhdr->n_type == NT_GNU_BUILD_ID && - nhdr->n_namesz == sizeof("GNU")) { - if (memcmp(name, "GNU", sizeof("GNU")) == 0) { + 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); @@ -168,7 +179,8 @@ __attribute__((unused)) static int elf_read_build_id(Elf *elf, char *bf, size_t 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 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; @@ -180,7 +192,8 @@ int filename__read_build_id(int pid, const char *mnt_ns_name, const char *filena if (fd < 0) goto out; - if (fstat(fd, &sb) == 0) { + if (fstat(fd, &sb) == 0) + { snprintf(bf, size, "%s[%lu]", filename, sb.st_size); err = 0; } @@ -193,24 +206,27 @@ int filename__read_build_id(int pid, const char *mnt_ns_name, const char *filena 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; + 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) { + if (!sym->syms) + { return -1; } Elf_Scn *symstrs_sec = elf_getscn(elf, shdr->sh_link); - if (!sec) { + if (!sec) + { return -1; } sym->symstrs = elf_getdata(symstrs_sec, NULL); - if (!sym->symstrs) { + if (!sym->symstrs) + { return -1; } @@ -224,22 +240,26 @@ static int get_symbols_in_section(sym_section_ctx *sym, Elf *elf, Elf_Scn *sec, 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) { + if (!sym->syms) + { return -1; } - - sym->rel_data = elf_getdata(plt->plt_rel.sec, NULL); - if (!sym->rel_data) { + + 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) { + if (!symstrs_sec) + { return -1; } - + sym->symstrs = elf_getdata(symstrs_sec, NULL); - if (!sym->symstrs) { + if (!sym->symstrs) + { return -1; } @@ -263,22 +283,27 @@ static void __get_plt_symbol(std::set &ss, symbol_sections_ctx *si, Elf s.end = 0; s.start = 0; - if (!si->dynsymtab.syms) { + if (!si->dynsymtab.syms) + { return; } - while (index < si->dynsymtab.sym_count) { - if (si->dynsymtab.plt_rel_type == SHT_RELA) { + 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) { + 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 { + else + { return; } index++; @@ -303,26 +328,31 @@ static void __get_symbol_without_plt(std::set &ss, sym_section_ctx *tab, s.end = 0; s.start = 0; - while (index < tab->sym_count) { + while (index < tab->sym_count) + { gelf_getsym(tab->syms, index, &sym); index++; - if (sym.st_shndx == SHN_ABS) { + if (sym.st_shndx == SHN_ABS) + { continue; } - if (!is_function(&sym)) { + if (!is_function(&sym)) + { continue; - } + } sym_name = (const char *)tab->symstrs->d_buf + sym.st_name; - if (tab->is_reloc) { + if (tab->is_reloc) + { Elf_Scn *sec = elf_getscn(elf, sym.st_shndx); - if (!sec) { + 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.start = sym.st_value & 0xffffffff; s.end = s.start + sym.st_size; s.ip = s.start; s.name = sym_name; @@ -336,7 +366,8 @@ static void __get_symbol(std::set &ss, symbol_sections_ctx *si, Elf *elf s.end = 0; s.start = 0; - if (!si->symtab.syms && !si->dynsymtab.syms) { + if (!si->symtab.syms && !si->dynsymtab.syms) + { return; } @@ -356,7 +387,8 @@ bool search_symbol(const std::set &ss, symbol &sym) { std::set::const_iterator it = ss.find(sym); - if (it != ss.end()) { + if (it != ss.end()) + { sym.end = it->end; sym.start = it->start; sym.name = it->name; @@ -381,29 +413,34 @@ bool get_symbol_from_elf(std::set &ss, const char *path) int fd = open(path, O_RDONLY); Elf *elf = elf_begin(fd, ELF_C_READ, NULL); - if (elf == NULL) { + if (elf == NULL) + { close(fd); return false; } Elf_Kind ek = elf_kind(elf); - if (ek != ELF_K_ELF) { + if (ek != ELF_K_ELF) + { elf_end(elf); close(fd); return false; } GElf_Ehdr hdr; - if (gelf_getehdr(elf, &hdr) == NULL) { + if (gelf_getehdr(elf, &hdr) == NULL) + { elf_end(elf); close(fd); return false; } - if (hdr.e_type == ET_EXEC) { + if (hdr.e_type == ET_EXEC) + { is_reloc = 1; } - if (!elf_rawdata(elf_getscn(elf, hdr.e_shstrndx), NULL)) { + if (!elf_rawdata(elf_getscn(elf, hdr.e_shstrndx), NULL)) + { elf_end(elf); close(fd); return false; @@ -426,33 +463,39 @@ bool get_symbol_from_elf(std::set &ss, const char *path) Elf_Scn *plt_sec = NULL; Elf_Scn *plt_rel_sec = NULL; - while ((sec = elf_nextscn(elf, 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) { + if (str && strcmp(".symtab", str) == 0) + { symtab_sec = sec; memcpy(&symtab_shdr, &shdr, sizeof(dynsym_shdr)); } - if (str && strcmp(".dynsym", str) == 0) { + if (str && strcmp(".dynsym", str) == 0) + { dynsym_sec = sec; memcpy(&dynsym_shdr, &shdr, sizeof(dynsym_shdr)); } - if (str && strcmp(".rela.plt", str) == 0) { + 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) { + if (str && strcmp(".plt", str) == 0) + { plt_sec = sec; memcpy(&plt_shdr, &shdr, sizeof(plt_shdr)); } - if (str && strcmp(".gnu.prelink_undo", str) == 0) { + if (str && strcmp(".gnu.prelink_undo", str) == 0) + { is_reloc = 1; } } - plt_ctx plt; + plt_ctx plt; plt.dynsym.hdr = &dynsym_shdr; plt.dynsym.sec = dynsym_sec; plt.plt.hdr = &plt_shdr; @@ -462,13 +505,16 @@ bool get_symbol_from_elf(std::set &ss, const char *path) symbol_sections_ctx si; memset(&si, 0, sizeof(si)); - if (symtab_sec) { + if (symtab_sec) + { get_symbols_in_section(&si.symtab, elf, symtab_sec, &symtab_shdr, is_reloc); } - if (dynsym_sec) { + if (dynsym_sec) + { get_symbols_in_section(&si.symtab_in_dynsym, elf, dynsym_sec, &dynsym_shdr, is_reloc); } - if (dynsym_sec && plt_sec) { + if (dynsym_sec && plt_sec) + { get_plt_symbols_in_section(&si.dynsymtab, elf, &plt); } @@ -478,7 +524,8 @@ bool get_symbol_from_elf(std::set &ss, const char *path) return true; } -struct symbol_cache_item { +struct symbol_cache_item +{ int start; int size; char name[0]; @@ -491,34 +538,40 @@ bool save_symbol_cache(std::set &ss, const char *path) bool status = true; int fd = open(path, O_RDONLY); - if (fd < 0) { + if (fd < 0) + { status = false; return status; } int ret; ret = read(fd, &len, 4); - if (ret <= 0) { + if (ret <= 0) + { close(fd); status = false; return status; } ret = read(fd, buf, len); - if (ret <= 0) { + if (ret <= 0) + { close(fd); status = false; return status; } - while (1) { + while (1) + { struct symbol_cache_item *sym; symbol s; ret = read(fd, &len, 4); - if (ret <= 0) { + if (ret <= 0) + { status = false; break; } ret = read(fd, buf, len); - if (ret < len) { + if (ret < len) + { status = false; break; } @@ -536,24 +589,28 @@ bool save_symbol_cache(std::set &ss, const char *path) bool load_symbol_cache(std::set &ss, const char *path, const char *filename) { int fd = open(path, O_RDWR | O_EXCL); - if (fd < 0) { + if (fd < 0) + { return false; } int len = strlen(filename); int ret = write(fd, &len, 4); - if (ret < 0) { + if (ret < 0) + { close(fd); return false; } ret = write(fd, filename, len); - if (ret < 0) { + if (ret < 0) + { close(fd); return false; } std::set::iterator it; int v; - for (it = ss.begin(); it != ss.end(); ++it) { + for (it = ss.begin(); it != ss.end(); ++it) + { v = it->start; ret = write(fd, &v, 4); v = it->end - it->start; diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf/include/symbol.cc b/eBPF_Supermarket/Stack_Analyser/src/symbol.cc similarity index 99% rename from eBPF_Supermarket/Stack_Analyser/libbpf/include/symbol.cc rename to eBPF_Supermarket/Stack_Analyser/src/symbol.cc index 120a6ab6e..72b353dc8 100644 --- a/eBPF_Supermarket/Stack_Analyser/libbpf/include/symbol.cc +++ b/eBPF_Supermarket/Stack_Analyser/src/symbol.cc @@ -13,7 +13,7 @@ #include #include "symbol.h" -#include "elf.h" +#include "elf.hpp" void restore_global_env(); int attach_ns_env(int pid); From 712fda4cd62c2b972af7cd6320a53f58b06939d8 Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Sat, 9 Mar 2024 12:19:51 +0000 Subject: [PATCH 02/55] update introduction Signed-off-by: LiuLingze --- eBPF_Supermarket/Stack_Analyser/new_bpf.sh | 31 ++++++++++ ...77\347\224\250\346\226\271\346\263\225.md" | 58 +++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100755 eBPF_Supermarket/Stack_Analyser/new_bpf.sh create mode 100644 "eBPF_Supermarket/Stack_Analyser/\346\241\206\346\236\266\344\275\277\347\224\250\346\226\271\346\263\225.md" diff --git a/eBPF_Supermarket/Stack_Analyser/new_bpf.sh b/eBPF_Supermarket/Stack_Analyser/new_bpf.sh new file mode 100755 index 000000000..c5266bcfd --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/new_bpf.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -ex + +origin_name=$1 +upper_name=${origin_name^^} +array=(${origin_name//_/ }) +name="" +for var in ${array[@]} +do + name=$name${var^} +done +class_name=$name"StackCollector" + + +cp include/bpf/TemplateClass.h include/bpf/$class_name.h +sed -i 's/_TEMPLATE_H__/_SA_'$upper_name'_H__/g' include/bpf/$class_name.h +sed -i 's/TemplateClass/'$class_name'/g' include/bpf/$class_name.h +sed -i 's/template/'$origin_name'/g' include/bpf/$class_name.h + +cp src/bpf/TemplateClass.cpp src/bpf/$class_name.cpp +sed -i 's/TemplateClass/'$class_name'/g' src/bpf/$class_name.cpp + +cp src/bpf/template.bpf.c src/bpf/$origin_name.bpf.c +sed -i 's/TemplateClass/'$class_name'/g' src/bpf/$origin_name.bpf.c + +sed -i '/#include "bpf\/OnCPUStackCollector.h"/a#include "bpf\/'$class_name'.h"' main.cpp + +sed -i '/auto cli = (MainOption,/iauto '$name'Option = (clipp::option("'$origin_name'").call([]{ StackCollectorList.push_back(new '$class_name'()); }) %"sample the '$origin_name' of calling stacks") & (SubOption);' main.cpp + +sed -i '/OnCpuOption,/a'$name'Option,' main.cpp \ No newline at end of file diff --git "a/eBPF_Supermarket/Stack_Analyser/\346\241\206\346\236\266\344\275\277\347\224\250\346\226\271\346\263\225.md" "b/eBPF_Supermarket/Stack_Analyser/\346\241\206\346\236\266\344\275\277\347\224\250\346\226\271\346\263\225.md" new file mode 100644 index 000000000..2f393cbd5 --- /dev/null +++ "b/eBPF_Supermarket/Stack_Analyser/\346\241\206\346\236\266\344\275\277\347\224\250\346\226\271\346\263\225.md" @@ -0,0 +1,58 @@ +# 执行过程 + +1. 若匹配全局参数,配置全局变量 +2. 若匹配子命令,向收集器队列尾加入对应收集器对象 +3. 若在子命令后匹配到其参数,相应地对收集器队尾元素(也就是当前子命令对应的收集器对象)的配置进行修改 +4. 若再次匹配到全局参数,则再次配置全局变量 +5. 解析完成获得一个初始化完成的收集器队列 +6. 若全局中配置了被跟踪命令,则创建一个子进程来执行,并获取其pid设置为被监测pid +7. 遍历收集器队列,为每个收集器设置要跟踪的目标pid,然后加载收集器的eBPF程序,然后挂载 +8. 若有被跟踪子进程则唤醒 +9. 间隔固定时长,对收集器进行遍历,输出收集器收集的数据 +10. 监测时间耗尽、收到退出信号或设置的被检测指令退出时,遍历收集器队列中的对象进行eBPF程序销毁 + +# 使用方法 + +若要添加一个名为 `` 的eBPF调用栈采集功能,则可以项目根目录下运行如下命令 + +```shell +new_ebpf.sh +``` +详细过程请阅读脚本。 + +然后按照如下说明分别进行修改。 + +## include/bpf/StackCollector.h + +1. 若计数变量类型为自定义结构体,则在`C code part`中定义,以便eBPF程序代码`.bpf.c`可以使用。 +2. 若数据标度`scale`在包装类`class `初始化插入收集器队列时无法确定,请声明一个根据传入参数设定scale的方法`setScale`,在相应的子命令参数解析时进行调用。 +3. 可声明其他辅助函数 + +## src/bpf/StackCollector.cpp + +1. 实现包装类初始化函数,若数据标度`scale`的值可以确定,请在此初始化 +2. 若标度无法确定,则实现`setScale`,对标度及包装类参数进行设置 +3. 实现一系列虚函数:`count_value, load, attach, detach, unload` +4. 可实现一些辅助函数 + +## src/bpf/.bpf.c + +1. 通过修改`DeclareCommonMaps(__u32)`中的`__u32`设置计数变量类型 +2. 可声明额外的map和全局变量在eBPF程序内部使用,但不会被框架输出。 +3. 实现eBPF程序,请使用通用的`eBPF map`进行数据存储,使用通用的全局变量进行进程和数据过滤,否则无法正确输出数据 + + 通用的map分别为: + 1. psid_count:键为psid类型,值为 1. 中设置的计数变量类型 + 2. stack_trace:键为uint32类型,标识唯一的栈嗲用路径,值为void*[]类型,存储栈上的调用地址 + 3. pid_tgid:键为uint32类型,表示pid,值为uint32类型,表示tgid + 4. pid_comm:键为uint32类型,表示pid,值为comm类型,表示进程名 + + 通用的全局变量分别为: + 1. u,k:分别表示是否采集用户栈和内核栈 + 2. min,max:表示计数变量的大小界限 + 3. self_pid:表示本项目运行时的pid +4. 可增加额外的全局变量和map。 + +## main.cpp + +向`Option`中添加自定义选项 \ No newline at end of file From c4dfae91d5325d09a3570f7d608dcb2e4a159242 Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Sat, 9 Mar 2024 13:19:08 +0000 Subject: [PATCH 03/55] update action Signed-off-by: LiuLingze --- .github/workflows/ebpf_stack_analyser.yml | 59 +---------------------- 1 file changed, 2 insertions(+), 57 deletions(-) diff --git a/.github/workflows/ebpf_stack_analyser.yml b/.github/workflows/ebpf_stack_analyser.yml index 18308fff7..753ebb94c 100644 --- a/.github/workflows/ebpf_stack_analyser.yml +++ b/.github/workflows/ebpf_stack_analyser.yml @@ -28,61 +28,6 @@ jobs: - name: Run app with native lib run: | - cd eBPF_Supermarket/Stack_Analyser/libbpf + cd eBPF_Supermarket/Stack_Analyser make - sudo ./stack_analyzer on-cpu off-cpu mem io ra -t 5 - - - bcc-project-build-and-test: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v3 - - - name: Cache BCC build directory - id: cache-bcc - uses: actions/cache@v3 - with: - path: bcc - key: ${{ runner.os }}-bcc - - - name: Set up Python 3.10 - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - sudo python -m pip install pyod - sudo python -m pip install psutil - sudo apt update - sudo apt-get install -y linux-headers-$(uname -r) - sudo apt-get install -y python-is-python3 - sudo apt-get install -y bison build-essential cmake flex git libedit-dev libllvm11 llvm-11-dev libclang-11-dev zlib1g-dev libelf-dev libfl-dev python3-distutils - sudo ln -s /usr/lib/llvm-11 /usr/local/llvm - - - name: Build BCC - if: steps.cache-bcc.outputs.cache-hit != 'true' - run: | - wget https://github.com/iovisor/bcc/releases/download/v0.25.0/bcc-src-with-submodule.tar.gz - tar xf bcc-src-with-submodule.tar.gz - cd bcc/ - mkdir build - cd build/ - cmake -DCMAKE_INSTALL_PREFIX=/usr -DPYTHON_CMD=python3 .. - make - - - name: Install BCC - run: | - cd bcc/build/ - sudo make install - - - name: Run stack_count - run: | - cd eBPF_Supermarket/Stack_Analyser/ - sudo bcc/stack_count.py -d -f 5 - - - name: Run load_monitor - run: | - cd eBPF_Supermarket/Stack_Analyser/ - sudo bcc/load_monitor.py -t 5 + sudo ./stack_analyzer on-cpu off-cpu mem io ra -t 5 \ No newline at end of file From c2892288b13ed495ff62a51aef69566c69d7bf8a Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Sun, 10 Mar 2024 04:19:22 +0000 Subject: [PATCH 04/55] modify submodule Signed-off-by: LiuLingze --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 62a40485a..19f97eafa 100644 --- a/.gitmodules +++ b/.gitmodules @@ -46,8 +46,8 @@ [submodule "eBPF_Supermarket/CPU_Subsystem/libbpf"] path = eBPF_Supermarket/CPU_Subsystem/libbpf url = https://github.com/libbpf/libbpf.git -[submodule "eBPF_Supermarket/Stack_Analyser/libbpf/libbpf-bootstrap"] - path = eBPF_Supermarket/Stack_Analyser/libbpf/libbpf-bootstrap +[submodule "eBPF_Supermarket/Stack_Analyser/libbpf-bootstrap"] + path = eBPF_Supermarket/Stack_Analyser/libbpf-bootstrap url = https://github.com/libbpf/libbpf-bootstrap.git [submodule "eBPF_Supermarket/Memory_Subsystem/blazesym"] path = eBPF_Supermarket/Memory_Subsystem/blazesym From 06d585e7be650c4a174620280ce49ff3bb3fb7c1 Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Sun, 10 Mar 2024 04:23:19 +0000 Subject: [PATCH 05/55] remove assets Signed-off-by: LiuLingze --- .../assets/UMLClassDiagram-bpf_loader.jpg | Bin 76507 -> 0 bytes .../Stack_Analyser/assets/file-blob.png | Bin 97083 -> 0 bytes .../assets/image-20230528173033-5c60np6.png | Bin 51085 -> 0 bytes .../assets/image-20230528174207-3lf5d5j.png | Bin 73285 -> 0 bytes .../assets/image-20230530164150-2f9ylpx.png | Bin 30567 -> 0 bytes .../assets/image-20230530164224-dyz4p0y.png | Bin 184417 -> 0 bytes .../Stack_Analyser/assets/stack.svg | 4757 ----------------- 7 files changed, 4757 deletions(-) delete mode 100644 eBPF_Supermarket/Stack_Analyser/assets/UMLClassDiagram-bpf_loader.jpg delete mode 100644 eBPF_Supermarket/Stack_Analyser/assets/file-blob.png delete mode 100644 eBPF_Supermarket/Stack_Analyser/assets/image-20230528173033-5c60np6.png delete mode 100644 eBPF_Supermarket/Stack_Analyser/assets/image-20230528174207-3lf5d5j.png delete mode 100644 eBPF_Supermarket/Stack_Analyser/assets/image-20230530164150-2f9ylpx.png delete mode 100644 eBPF_Supermarket/Stack_Analyser/assets/image-20230530164224-dyz4p0y.png delete mode 100644 eBPF_Supermarket/Stack_Analyser/assets/stack.svg diff --git a/eBPF_Supermarket/Stack_Analyser/assets/UMLClassDiagram-bpf_loader.jpg b/eBPF_Supermarket/Stack_Analyser/assets/UMLClassDiagram-bpf_loader.jpg deleted file mode 100644 index bcfa0292ab7ef6b770b1fe2db956379176ba9f49..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76507 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 diff --git a/eBPF_Supermarket/Stack_Analyser/assets/file-blob.png b/eBPF_Supermarket/Stack_Analyser/assets/file-blob.png deleted file mode 100644 index 84c77a32de8dc1c5808677f9c66622caaef44b9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97083 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⪼`5 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

Lb0 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

;Un; zo0XLn&!XStyra>v0|G5#KCEW~O21tYNF4Rw^^1SkFaBLu0uMLqkGGwvLVe2*62X0d zs37sY!?(!uz1ecZHUsvS$A6sgg8X1z5ftV7;RHlbDAXA$O8FLG?!SU@UcRjLygD9C z;U;v9zg=n%#HJ8p+BbL z1M~dxSiSXmpTwJ+95!824|>v3okhOK9uA`spjT?yeEbM>BzHetq_?uRcJM4EB{K4G z;;;qavz@oc>F*XE#iHT`twsPIttA+a&qsk(Ypv7`4HvVn|7?8bp+0ZS&d;~7vnwn6 zoI5bw5K_O(lQTEn%3}K+I^8g308Iw7I`BjBXe(6pPNMV*!K}6&%~zEFR^xv$}B$i zZjhWXI1#_QQvI-A&(*&(JR>G3@L=X;ST}R^p*ft@UDH~LTH4x2R~iBCdCYLErc)lZ zv!5L3+_goT^FKR6hc`~HUb#1|Gkb4)Tt{Vv-5*YlaqnC7Yo6O49Us0H_+l%XK-u_d zcu_WGvaE}PeeL9GeO*F*rv~B9LnkS0L2vMP1ZhOF9$vvU0X&MPDEx2sE$cEt->#4!X%$7{0S?WvIz zHREdz^vNj?&z+&c6m=%27mG~gFrH3d%;lHGPC4`xDV)|08*Yg*j3W~<$g=dN&zJk{ z3un7Qn|%wNX=uYkZh1A<7TAXHv(2m7kBY_5kCrG_Vya`PEuI=Q6KK7M4P7`wvI_T- zOIl7LXL^|tWuaRhYdx27wA}I*2g(sJO;Vm}!|IDn+`jl<*h5hJ5k8)qQn=Y2D-P&K zWUTd~W~q*uscFtW5G6k)vJ0%R%vb4FD&!%*E=WkQhxbZnX|AQhQ9{cJj$sDA#M&*oD~z}a!jT&A;kUqOpG^6tyV z&^|)zsG;iq?%Me%d`^)iG&tzcX3k`6;rq$`l%{grk%I*&J?1e;y#4oY+Uz&CJ08S(gfuOZ_0VFAII~vmrGzJDf*cC+H46_)RH)4$xPVY{(6mtnM zXJzO!o>5e9zQIM^T}Y~M&+=A4C0Rd*`jYi7*7ixY#qFdyC@Ge3$Vfz<3@O6C@G7dN$W%xWcLxwR?JaCz&A$2%k{r%n0|ujaB4 z)|*dA(w8xb*n2gjVyMq<^9g34?-^n5jyuQRgTc$w*jtN{rSHo|*_pLp6P|CcR<_h# zlP>=+`9tGu7qD^cBBAL9P88;!PHSL!o7W`a*ue-Fe z6z;;VdV`wP33W1-b(MLjLw|LT8zH(VnI=O%o;Dt6k5RX^HG^Ozkl>d}J^tdjn0F}b zxp(%3)YSY_DU;^A`nq)`2C)vR{2YrY|GRoFMycie&*IYk10ssrr4KX|g6VjzHV8kT ztnE7cg&O-9BskhvQ$1u@QIF&QpF@l4D|=4US5-=XkNywQfyA?H(Doy+_dHVz=J3QJ zA&&J@&t~d2&TrUwC%sLjMuqHqa%O_aF&Q?kydeeurzVh>vMBdw#qMTG&0m+w`u=bBNH7yJX|yJ_jR@R z1=c#*5_`F`5r_bCU^Zil_6(k6RQE?l7XA+{!1xNzNKAIXE>W!XtXT$O1wli!|G~16 zLaY>oh!u;}gDtn5R@dkDr*~%tSF_H3o#A~J(3>BAJ-L=d#^BMhm90;4Gn_4E(kd#W zBiWLwDk@po*(S!usNYpMgVOAnzo;81Hyer!?3b%j6$CBocLWjaY+wWp;ShF@B!gZqi0qF#Lh15iDQc z{Hv4B!kj!=ssR;oI`4~baP8zsbUJ$p?ecDd4ou8AUsJ%3;i;3OweXj$ylkeP_ZoRL z=4pXQ2@4$DqqOEJ)+D9PbO3-7luxnNRVef0TE=zK<;pF8=IM`TUU6(Rw3mTEfR6kn zicR1>&Qf3Zrq1c*hmxCw>|LMMPxQA0KteQ~)fTyIu2y~JGyELa%IZ)8)HpShxVUTP zT~}|uUY|D(9mbhEc0MDDCRAIQHvJPecHcBjvLR6U>*pd@NybbDEVQ@|(QHnvoAQdn zVQ*b*bR~kUxW~6kx$dt<{GGFZr=1pJ(7vxbC8tw+R_r6aR=;ojm=`KS9dsB2wd3gWuVb> zhY;ftgJ{)M!noW;_=#Fxt~gcs>gLu*ljwSB$ASEW%qUWDW2(RommYiJSunFEY_mR$ zdmZaDU!DD8alsS(7w|i=Kprh(hKOrho8sT^LonQq=vl&GmsmqXahF$<75|HD{ZkQQ zxZonDuC z`QKP1sXT5ECubPBQKc>Q(k)Z4^i!r>)LZmck%Sq`GbqKpnpLKZCPFRG!sMvHt)5m#N`CgocX^meeZ z=ZS7$t14|m=;Q(h6-b9SBr^3!$u)JuGU$|@qgF;TJ^GRg84(_S_kjcj<$JMaIbvoePOCgP^?zi; zE$oC1KKv6f&l$hR=&%o5-zk(4-dunA-+X2b#Ay(Va=kRw@7GtIc0|n@pm;I2v1ePm z{_7=B9qT(wV_R(A_owGBCfhB#|1VV|D8i!PeJtq7!$Gkn=zDqpWhd5oIZn2qkd1n5aYy9GK zceR1Hqv)Vy|JPtWzVG3z%3^$g{^e|Z$J`^K7_w^xE!Sh09bbswMk;h!Sy5cIQFx;%j&f+S^L#QZ6-y)z;bdt;z;(8(BwVXyQ+_Mrp zQ@+2aI&0LU+2!OYb=JX&4=6-A6ju5RLfgc^+>Sd`>U+pJ6|7}1Fj#++s$b=Ee&#jkDbzm zN|oDDEbdr-$3RPkM4qwSOoOfZTC3)5VACbuDFf|)kg)a?yv*Ykjv%&%ouaFk_aBxs1N4|ulVr(I=H-XB^%KG^DoSjzLJZO?YAggMok2jJ;xKYLGos`^!xDM$pULE^QL^s0+ zzsJaS21_h#Z*o;VqomT$-NaZ1htLZRefu#RPIp%ONoMxq%fyKJCu~iN#@r0UyHgTh z>*9M+W$`!^R7FSitIg6KsH}cY3vjKcqUj#2U@wzRYR)_aT)DfuGcq#jBPJvy#0rdw zj;`{)btfZB6Y{#IJNT(?gbVa2;Oj^5gF@UqGvEJ>iRq2V;IPzY)S2Vj2&k(6Aum z-*-1FCiMCeDW7n0(;APUC4FCvFT1d8L=~ruj=nP6q)czpCbYL(^Ntr-X%~Ku(3pB% zSy@?aF${QCQ`I#(TBVXJlbM-GDH)#1?iOr^st?{C$?mQ+>4x=mcjrq+kX!B8&8X1a zKLw5>(BK=3V;{O`mGy)S*Hcd1D7YlKURq)l(e+VZ!Ott3TU&h1R{YHT&xx%BMGdfi&`osM48+;&ImNu9rx+%a#2hfrvp0>=K1O`B=paFs>y zssH|@kaVG9RwsS1!n;@8gxzk(H89hYx^dl;V+T<}Q9iNtNLp9>#27t?$9v(iJskZ1NmXwqPg8k*?<<-f?27mtDLEC*-cQ^9- zI{qVfNSgaegGnIP18h4xyyX-PM!j`dnWSKLwz3~$ke1m}dEDSUv^}aUC+Wwt zD!|%O7;f_su+oH|o}T)@Al#paYqDs1O8#0o($mxXASRZ=ZNGnTU~iLpuao!dJ38Zm zu0PlpU^zh`nW%wX)b-F~mf_)gkG|C_(j#i;;&6U}kK#YSx4iug5z~jaVg^hTG2(F^ z56qVjc)G3MrAr27)bIpgrt#G~o&|?_k;TVCAg^A9L#X5;Fck+coqsMFdQdk9V_|B_Q&8S5n#_Vye~ z<$dhCtnmaZP_@O~xl)TMruTe*erIp**58DeG(0@Ks|_Xh`9Io|PMnW3aclj3Jgm@k z@7LsJ(nKTAeqJb#qXO!zeFO?71|yag8}p*R4x)J|tjk%Wu(HynS~&@f?R^YQ$vz2^ zN>Ft;+td}CFUA>3gCl=W3$r+pF{^>;Rjd1MlkX2wkeWLFettk{W4^&bOxwi5!otdm z7#DYGXNTXoQjyZ*-!M-Qwj`L94Dwty5R2l^A(cBwa|*m6_~d%Xt`w zKLt5;tI0*($-Y&`)$z0U0KKeTZ9WJvt;aN<%2jgvfH`B-D7jqY5Mlc-ZkkPEFMRl9 zGwbcu-J3mBMhVWUnO(Z4hpHD&ySr@!3AJyfig|pR`@aH% znfykwYVkC7R3Ar6YMS?wzb`l5`UUF^=N zhIxJ0`>zZVD+vHEz<)%wMTFJ2bE}CWe}8{Y>&bz|#l?;eNQaNEQ1!}qklkre z#U-bxIn_A+8DR*a|JbTo_GAyTy1pKtltdpT)tdZ+Y#d;vJ--7axsd0jQsdV8`eczh zBj-5~?SH(vpEtNW8A*D^-f3RCt@^F2j6Ryfg2rHj)kXnA+O@S+bP+!DOAWFbmTlw^ zlM;JgOa1okTVS%DKYy+=S@8@Z>~;O#>)MIx6YC&OLp!%toA+(27cw?QM@I+f#`X2J z)h@tGix{vUr5Iuj$tfinT~yg>snJ@zHj9={dL;&-l8MmqGVTjT29mf9(+&E?2{BfK^LqmEj+`PPQdx%GjTs$AWdQ)`Tp87aKMO6Y{)JlJ;96=@1xr0sFwRr+ zVW6_t@ysj?Ky-jQAE4y}0A}8-k3djRkkbYGIranj4~nJMHc6Ojj3Vu~>){xhN;}A< zuIJ@AXqI;WpP(JT+JpI25YF|wzGRklH*0tx2R%#!o2HCwYrIv^8j5=EB#lj6MkYsU z8&K%#zArv25Ovi&SPE^0560UI&gikO`UOrEq_yO|x@WxQ;}S(iQ_K2&c&ppK<~Tn$ zr=qIrCP0o?V@>+6`lb}$V;pS&G4)=+l6CuKG-{S~B*?|pf=`i+crSWm+&v-v*wP=s z-8i_Ege{6bVvrnFKR;kZZLJ0INseJ0z;@RQ5Yh^VO3OMqNt$@1AEgAXZN|9jNyYf;0r7Ld!nkG z0)yTQUbo}b676b7>Q4z$RNC6wK#iB)am1t1Him&Gx8c z%$uJ!UQBhqEYBiOeIb-GzaCiLP3Ks`7P{My8KSPGH9e5Tp^jfOi$DOoB*5SQ>iRmI znDhBF1Si>lp&Yx)CG}L_-9%GPqp8V5M)-{fq~d5#(U>c7XFn9?2`n9H`#+Yek=et`Vm46(tCp-teIB#wIX)&$5s{v4tk z3L`gcD8!=)TPvPC{*}u6C7eRItb~o58~XY4(`V0!xNH*3%USVi64)N<(`$&RwHVuf z<{>}mB|H;th^&NPug{=@k|k*Rl$gXKWUoXZ?9zxT)#_>Da4KGP1xU`|#0D-dZu>JN za@2rV*=FFo;hpZqL^c0O$@B-;0VH(9zP#B@Z&o#`O5Q!u*KFt0bVldA-y2>)s$akwyM3c(l*LPf1<08^#QQP?T0L z7v%Tf+cmlqE{3>WpB4f!eWg3&UOh6;3{(bRJA&7c> z8ovZlC!>{s^{K-e5ncJ6G>)d6&;ASX4?aHk3Tb@w*)HS}8+&`Da(}`LT5Q^ZKL6y7 zf%#i5%aw(v2SthAG3P{g#1aJXAo#Aky3h>uPWy6l^JH>OO|7!R8VSCFjrDVPW-7^b zNJl3*$7sRe^hRV{66^5X;tAbR%&YE-Ow|pIGK0#>^7iOxSkLbdM^AE#)R6*76fZ9i zl|H$rW|ryG9(YeM$!9c9;>Zwz+hzD55O;HDmT)*dWq7LUFO5K$)YPA~ZTkZ(fjJ6# zx%Yo6Kk1a}I^1w&@HzJ_E(+U!J0BPrn1@5BN_FdBmp#jU0j$Zd_L0Q+>^?(tKgTrL zVXy+@S{*UT+nfGBWqrTYQV$(Qs@A$uhN+&vOrm3AXo8aSeA=(Uy#{pXCDZwP?()l< zpG&Qs5)r*dOU*AMgu3ve{L{v2v>5}T)>_A`&wuQWa8_8U%rj`_#&eZ_$#zInx3Vdj zw<-BT(a%vsw927fn-}n9$WX3K*{i;*F@n8{Y{D23aeDRQ_wV1ZPe6v;M-0%+LKzgV zUU30MOn{W76!qYJK$2f!Qo!Mx9uHRaZW$cu8|WFBpjm1!-4{d)=={GQL%Xo|FI@u6N7z6btwx0AT&5fM;gP9rE;u zVv$3@Xf`#9EM$ZF@z?bzDJt0n7X4<|%BleQKjirMs)Z`Kd$aXGXep}nQ2PCFu;Jj& zznELcYuF2s&v{`XXO``-b*9C=#(^8T zA6SkeGUIS{y!H&ArrGU8LVIO(HK(*REitjdajlQb7Ew@X|Krs|b^W>cYZv67($8Qp zmJf1C#GV8tizQsZ{PJcGkOUw8{24HomJHQy>EXH5mrARnY^pC(fG}HWrxz?nz}Ur; z8tpXtdwvAT)(sOce1o}P*i7YVS7Y}=_}$ql-Xi#f z^FbLP0$Cj?xeXA$QL~P}ML=&CNc!Z1w0d53P}oI~JMd2}0osOCm{b*X@J3x1tCQwM zo42%WYvKL|v#zRaT_gj+>LNL)uL;PF!zhIB7Fs;|h-qnQf!DlxdZfU7?xzLUO=!7~ z9|ArYoTL|DEKzoh$yq4m)j93(F@Yxb3v0HnznGKbPL`qO{zq$1#D&##4_x%6-LMhw z9l6rmfk-@7kJs@%1hgeT*SrowKp=T)g6Fq4HxJ}T0wWp;5Q+Bp$%%=#S603(cLV{@ zt++l=iTL3yL^^{0;JE3>5t^3!qj6mb2;|6!)vh`8_%jq*qNbdX_@x`W()O-i;PZOq zH6-@vsA>7KxjrR0J+0-|@-xSI(7VxMC;>C0&NSi14(O}O#^y+N42^tnc(}%-tGj#E zGXx3>O3Hi7Xh7%FwJ*Bmo9_j1?lN&`WJM(SxX-ff6?7ZKsmx5XAorFlwBh6nSq`^$ z_=Gr;$x&sA4ERrl@S+45_aYV(=mC|dLd?3*Mzkemxd3J_PX3-2@7^VfI9@MTnr>{z z&ZDm?Z>Xqp!~(HeJT5dO_FPv%!uxbn8SrX+R*X*l-3k^+iN~Gm{)CLp z`wk1t*J8FX@!h({l*sZo1{fTE#HvbzpS`lQLJu$?<#%sVsd|2=NXWi`c7satVWuCN~u zdGEbnMLZN7nE6DwnT#xBd$QsSiXuN4Omj6ilh4cYaru3LB;~~O;q~v>w&{V-UMjJ_ zf4>R}Y+w3}fr&YB+ol{_rr)x?w#I2OL~1s^zrC$fs#ELd=LZn5v~S*kl=)Xf+TXbe zl>{TBA2e3M9Y1|hE)EvU=f)={#VT=Xjaw^gf^8TSXB_$@YPX9Xq|9|=N#rgKVu{k=Zk5g8cw*PTDq21bFtGLC~geZU8dLc^q zOD752?_BzUHCsiFue$0=JaZpo>8yenEmg)lU>}~J8 zjrIOd85KMQtTP&gRM(9mGBZp7aWgPj%~Y8IEE$l?hOd0z#A?YXp0!a?*V`g5|?0zW6`Z+0uKG@X)O;AB+#D+ zH5U*A2mh};`I8>p{cPiC#jwr0w8X*Ld17QlT1slV!NFvzOuy|j(@)K%M{*C(5|(*` zgF!CPU{ng&M=RZgu|K>zV7R1Ml40}T+0p(X{h!?UL6C>> zqQHveQY>(;7B>;b3O^z<|q8Q&9hbV{p0yzl=q zudg?@KuUqAv24Vv0Y-IabMpx*s+*fzVZDda!hi3f_v``GqVWCA34l@JIQyRL0qBK{ z*O3bFsQ3T!C`pPcShvKqXx3LHh_*zd|6 z1>_0;eHQ>|QfVLHj0XV_lJrAgR<^&tpHWayUssm|n7{FV3PI3X55R;2l0cuGN#=js zoSoefP~c=sgnjttLRZ^o^mj-q7g!gtw`E+K^Jzed<0~HcRS1A8TI}YVnx7$nv+&!K zJ*De7IOjegH2d^A*#0|p+c_Zl11zm-S4x!A>J8!Ey~WwilR^aF!@%__ zr1C5+FITyrSpmU(X=&;2UqJfmz1kC{4|jPBbg4WQbzcX_hAA}d_Jk|=Gei=NrhRxF z-F!KzcSdH!Y(0||bSoH?nUrOL3`k@Jcz0Gadj0Ok*fg|H;R;Ie0pe!;yt$j>(~-efA_s8*e57&hRQPHz&`h5ffNsn2t2v z0?_~4Hv|@;Ph(8B1-ofqi)BEi*BXWAWPYCQOj%D9t!->1L}gx9|LW}QoS5L`;&K5t z7eIadHi;8iiOv40&vJKp&}(hes5^yavve~eHnMymFu#=M<6=EE-I!bq-~ngu4Ky-9 z#NfaUEgp#ViNDhstJVo4=4@`Z;?Z>2?080Dam)9s+MQFeoOsvGYTRz6 z-YPKhEjZZ2rAhmQoT54qo&m45U1%O$nU-_mSZ~iJijj10P%qx!SI!Q|&xTL=S@whR zh3=o>-rwj|n*+3(%~hL!3fH~Rcww@&Gk1c!ZJ<%106+tMxwDFN-1YG|vzbdkc;COx zg#de}!l>QT)6<~Y_16QVxU#&AsIx@^g{yQy4R z$OAnm8f8R(%cF~Y?2-%Hjb+%z`9af}M1__9Wpzs1o#)Bv9xpsT+@j4nCRf~LXXIq0 z|8txM5p)Rs6#m)kWUD&OT0N_zL$n3H=!ReHp6-{J0M{6n=^39Fu#RLBBgK1_Iroy{ zOekH7DGFbCdj98-APrR!IlUa#T-)8~8b``Gxy_!P7(~UvU8;u!?0#Y%b=<1cSmpYj{2Wf^nxM_O+#N`cWNfBlEcASvAB$cd&@2c6(FxeAwKX+m zdW|Z@8q8-d*ncHsGl-yD3zWzi7397!5wY6VZ46jz5&ChXUO|N7-lCG-3eXr1Lbqej z&-A7Ti{Y=zX7dxFi*;ZS-4&X)G{>Gq_k+k75b6Tm}v_lfAT1QW9vHG!?TYf0F=M>|HuN*Hi( zb30q_7dPppub6u+|CGd$Ef(x3wnU=hgMKvQ#6-~t0;;Xlwhjeh3w^k!Ka3qCH1s5` z`zl;aCU9dogWDG2G+v+#s19Y~7yt|s6&2NXdp--~`Z%@U^B7ruJ^J83OfII8{Abr# z`=XFrBz?LG>B*bFecba|46-vv8!mOz<{dXLkax*LyG$<8KrY|=Zb8&y-(1? zZ@MStbZhM!7gv3=yU@wC6d|u%hBz6lsDpb8-4Z53*8hKey>(PoUEejl>28q*5fEub zLOPUANokSp=13zcAT8Y>-Q6G{-2&3xjdb%auj{_w@qEwsjqeQpU@(BQ_C9N`HGlIr z=UkzrT%XQ%1_{Km4@T;{XE+_E-+(gG{^_gSXI|FY?>TQoa9c1Y!NxE&t-aaRB4?8+ z_V#U8SnhDD7Js+R@5BD#yNgmnJUlvoorjC5RqbX<9xsz0Z34B2g2{sEqufpJLB@)$ z)eWX0MjTrT%~PqpRhePsFFo0Iv&iSJVoqONgF09AyzVAuXKyxupEneUKLAJiYi!Ko zcM%CWIlu7$F~1sGpZ76-9o0g89LxLPmW$)l@m~r!wpAB3mm6~u*vHCpf^;+Py29X zz6V7{22+q5c<2~0g?-N0(e^hyOuQ&>^X+fhtJq0C&8yMacv&MNH9zAmz`Ra?5$NR-9go+f zj6zdVQmU)ZKnulqARcH-Fu%L{vFB*ZwjihRU*0;LpMT8*fC#+u@`hQII?gHjHyH}9 zRt@Q0B6HAHb2}>if*7YuPUSuY<44ElS9}o!*q%|jim%>jw3G=}_O4OkMz?iP&(U)7 zSNoZWoxZ+tn3y2E9h?S(6V@qiEdumS#-4;TZxN&nyfu-ZYj8S8#*2(qZbXhj*W^3K z3e2M(q``}neWq3Z(LX6EiQQcNnQ3iBg)87c0C2*s?s%AP9QMvB;lf@TmP2LoYp%64 z{31$-m+ZZ?&={sxtYxul{>~z>xb(Lw__hYSYKT{ZRfYUX@RJ^UNJMRlhPM7NknDw} zA1&hXtzgPra>z=5_>Z zIxZS+x64-;{wgvP(?h~y^HZ8SpYCC>EDNsK<#LI7o*5qAFmi!)PxQ@evE`QI{u=Gq zE?c$hCqfRDmH6k6t|oJw-JJ3L9zJNo2t0|nPTQ|=^bR%&{dI{Ri|sYIR2@t|@x$G@ zhDShA3O%_|6Y42IgnT_0=2eokPUiappPQ2g8D2d@rsZ(b2o7DGcm`G<@aSn)8p}0f z%{bWG0}|QkY-a*skf1+~sJ&q&RC7!fY1;J(qSbNtj{HR>t-c$|ux78hnbN#p<9h*D zno9ejg+fBEe?0A^-feBS5+Ut>$G#3v``!;V1b7Gw5$yB~7jB6Cq$MIUw0dw>wI@`G zeJs)4TFY*t7K@It>EdDo3IAZZI=j*H%Vl6?&hU&@9It$Yji5l)Ezk&KD)i$vZ)&xj zDJ_w|bXV3?(>>pfW6D)%x~M^fyk8`88GX>wW%k1r)rk~4Y(qwbgr(b+&FPH1HzPJ$ z3#R)5M;^s|GoR5&ARlcEp5mOmea11N(s^Q{haLC|v@h=OZiKwanhirklCb~9E69S1eL0nX1T7ndI}o+giuVvt-7D)Q5zS%*U!t_TBA)K4l3@y z6Ayb>i&pS#RjVYE?VN40hvN*33bsAF+vv{r+T@(UG1?zS<>7T zkleu3H1N|$Zn1Hzf2H;wPZZS&HPO5_17YB8_$dzYlT`5eY7t{3dEMXFZV7BEq!HG9 z!fC^%ks#x`4Sdu2aYs@g9=rb2>nv?Wx3i5I3r=qSOtY)r=~sdL#e+LxNCGIK^|y;i z%5ux>L}LnFDK{pyF?P*f65qO+7j9RhMxip>4z?1mcCVwAEUGex5DI>YQ#&ps=m|!t zo*ObG%q}ihqAc_&B@zMBv*f8-4k_O`3;4}3Q?}a^P~Tx;JXBntdtg-b_hKV{{`|?H zoHMRFs;p_M+bnjEFH=dmruxuYRwL-QzRrYs3RAG$6FMFjkg5HsUwzU70U2!x6$w@_otd)MUK3dnZQKp%b^Y}HFXd@~8RnRkm20oYpJ4X2WRqgOKW+6qJ(wo@@6k4$y&lsNXDJzN!yPZqrD^Q z#DZ$CDnySsZ<)9~GY$9_(7Z+g7=T{8A4E$)abb@w$mZOCx!&s&r*t(-y5D*e*ZzFKqWrs z8L#t$8rm{XT+l`EXqrit+D}meKlBh# zBk93?`z9Y(EtO2}o(*6&00Gka!HLO)O=;D2MlU5~$R)$be7+KCay@4M%w3 z!W^9I-#k$OzYTOBK?L;Hb9L{`E5Uz3C;of+L2W=<0jP%Iuv9T3kvqN1==R8h&A zB_$HDc!DAG!d(^AwFZYUEFa4;Q(!u2I@xgwhT|YYSX*yrODD8b(*++aZQ zpF$}%GW+}G@hIu9`~V%G=P-d5NyAB$koRo1GE=g@4K@cwN7ugcx>{}=^`xIz-=LE~ z?IjfY`)UO@iT-G%GbG1{Pu$s0@np>?^rjL+;;9k_^r5fLEVRTmV=RW{6iZG{4omKg z@aJs-?yIf=2pZa*4IGjPftmi@kA477*9MfSCmV9I`=}YlJyN!%3vNe%P|)Xab{rOW zd%jgK@Fmm*kmLg$513>+nNr8Wuald6o~EXkyTN&@r^Lm@rKPFss_Go3Qf7&h;6jiD z_I{}s75KP#0wO7>$6f95<}mc;8y=ldLgay$8ZXJb`fi)1+5`oCk+F7!OwFB}ZHr|a zz1HJv1Cz3%qYEnyh85hgQ(M_wThj|n7l#X7U(W(u+E7?e=GW)5e@{M5O`g zdKN+0d9U*bF{~~vEnZbcyAL&N@%YugH+6)W%l%>PP&A zApUfA#4n z4ZI$XJlsVHA@Uh=TG@TS>s*;h%Nu=<3+n&~GF%9-@ho6b+MA=+(XT%iS%8PU(M-mMTDM=TQNJ$a&-mh&`+|YzWO*f zAQLzAz5s}EdIen=@h@F+@0&%=uFPkHSaxF-Zrqpsl^fxNyT`jGBGeSA$whLLu+Hk# z|CBP3rV7UbxP(`sX z$nV?`FbdjOC0Tj~9#PVbs|xOky~!(J;1)>#4ziUk|5)bMDv_II(JZe)Qs-{6bp{Qh7VEV#eqBn|h zAy80EOpM=?;B!GBq`&}i4%7@8x)$pn!OnX6uN!8A6irbHta6Js2&Jw zMY!+BEjnLo+3bX=oNuRD>&6X8;fbbDN=3nc7Jjm{{J0u5gH;&Yr%|}K=NBgAZD_Ko zUSst&G{jiwQ$lAk=Sv6Ce69)25W4GAyYnShLk)In9n1GwVY4hgxI2fHuY>gz`?%u6tPw z=IeT;bRp6X5nRNVCi5@Laaztps2zDzOh_oU8bMTQP(fx5vt_!qA1!D=VGPKCHuqvQ$JkuAbvy`@y=qBdDEAY`V|I^M&kel z{7@=tr1ol-W(kFaS0hr6!f|b{6z*DLU6Z%zSBLH@XZzw+FOvHV9^2g8^#)?FhzSN| zliuCJ&)m3wH|_hzP|VyQQ!jRr3?(J#&KzLJc0q416t3BHnvM4pRqvgY8;>yicHj(*O8~3@^1qW! z`J$wmjJ?6ESu{Eb_qBeLtBG4L;8@KK$3>;IGS|-oR&;L#wx<{itW3&n<#F8dQ%I?4 zDH3|$=?zfkmS%(S*}~G&-0uc2oEBn&|Pvq5biI9h+{^sS%w&^N+k59HRY zjgRlSeEePd^)cmV+#N%urwXSPyEl`OCrH_xeCXfSQf6AGrzh@qP6opFpZVO(4`g_0 zHv&I?#1XqiXROftU_2C|6A=l1fSVSte5sFs;A}nEc5wv>qch?wMd9P)w};)Yy}GIl zG;1&JvR`b{TyhXHObHn(-;g%h`9D2WE zJaX!vVEFz-3}zNPTRMMZJ@toh9I2XP!cAL~*f=-)SGxh&V$oYq=j-xM9P-F!9{0EC z)*5%Z?<@}CJFg7by}~FE%1p|;6G^k;z4~Hq!*jpb^p4dkKD7W{*nj7%|Kh=&Q%GSo zoRjTt1s&UQy%jMQwVz;c6CwaQf7{LVB=q^DG|1UW`E#6#l9W7hiBhV$2n%mOidP_d{IPM)Xlx}@@ zWOrIpoa8lK&UW1k1bNUCA;+c(TTWKnEPPg+49P^jzMu-AeiLxIHEIAvm_U^3 zd39_gF)Uf4(?UOYZ*iKdcUto+W9FHB$L8Qs#>~Y*U{y(ciP6NhN{&1{D<*UEPHV0A_TX(IJ4r zfPMnhTj!vAZfm=>h1M5WptNi+ZV{rJ*-bHE1s%W(lazixnQB>|HC^>DHc=NLr)B%rP5Mx57>qsy@icx9)sED93@sg=O zY>**cG8xBtVODFgk*X02OT5#oW>i3U-Mg1~?KV!3vb$EXXOw$%ckO--ftK2B7U#9u zts;t_L8c6-+_?>|8yDj-1VvTE5;etwWXj{?n5|cqRhsPi6xYcA}VS*FZo7B~-&6ammvq341<*g3R zj}@~@GF{Zm-onH}fM1A)AoQy6%f*Z3vBfS59W`lK+HPasL2V+EdX{s_@HB_e(Ky#b z?|wp(A3(Q|aPDk|5hzlD(bdAk3)#0Eq>&(DJpMvS&Sm+JV*c)2%WhcycM!J*soTID z*TdALmp|N(4vg7-HcO)Bi$aPymHe>bB7Dd@>9I>$=dQx$>nwC8{w+3E`r~^) zMS6c3qmk|eL5~JNih`x@*X9KGbE7M_8xyuZUm{WFzhvFdV?h5Vj%a8M(NV~ z{((#04>ZuNlU3hCrgex>6egwDa996pJDBfjdWnaFamJi7YqWTriO5$?0 zT%X+5l;-45?q_FOHSG6fTlEWRca^Blo1>KGkbY&Et$D|%)ZA3#c6fyd*;2Gx4qm2m zB7BRBQBCB#y!~^>&R9J;BrVx*eLoJDiQRud~OMVNTi;R+mzNfAG zf}Wlm^764yg{z@wXIiEOPwO5zJ>fXh_Y})c@Jv(vthd8B3NeZUJD4g`SC<36I)$v8 z$Bnc-GpJ4(Wp}4NB*t$ZQj3NtFSG8(RzAv|wGICcwBW=?DQKPAc0872hugptVVieS zp}Q2V3i{;LMV*ZVJfHt+0kUa8_&bPb;S>NZlHpVV3w{03BUVrkfb@c+Bip~TqWXkl zSk~hYS1uxSI$&ifdukpYN7MrNwzJ+46*wv4*+w}EZf&jNNQ)`X#eE$mZE+EXzx>XG zY?>H_tm}PV`d1u?_nDgWhDx^f(Voaubs?pUcA+lQzSf`c0q!G7Ps zEMpD=9CYf=WG||Gpx5ZQuS+s=efgDg`7n(01+5uyJ1{@SKnQ161nkG}-v@aQ8)f3& zf-_5PR`cS;1iWr0qkoQYyb8E}+t0qd`Iuf0_`JjYJ>Tesi6T5jB?s&vZQJOSr%iXq zve@~~rh7zZ$a9{~zem4vS94nx^`q=eUiscnCy}K-CPMg8^m&(5W*_>2N?LQUwlFOD zsd0NJRVJ;(dh*pb8{jUPEY(wxm2I+Lm$tZ8h<~vR_>zJG_KSX{T;q@XmLKPP>{R7^ zN0m3K>Q-G(<_Gq421v=PVEgk+#KjVN50oB4Mat?N9B1qtRy*H^bU%YH7CC?xeq#Fa zi4Nu$l~n%V2qEAziW?5CX5&A5FRWZU!sXtL=gDa`Pof73ns+|Ij6jc5%4+>O9X(og zmTQv2^t;l9Nd)uN?ztWG1hFgaoMdXeXkhOd&PUdI4K+_bSM`-THj4QD8?F-m{DJ~> z92_s;RtEdvQyP%H@27>ro*?Vwbhff0zQB&2BEMK=7ENBF_m}(Pdr?O-?&E(i!F??^ zXd)DEXWFhTkInF@@lW3nS>+^x+{w=M*Qz=i>p;KRq1ReN{QM5#c+E?SYkDsH)mOf8 z!C`OIpOh>ty1(8=g38_tU=Ir(ny7j`)cJ5zzgu62M&><}Q_Nopr55oMsexf({ATrv=k+AV=Q$fdNafoMB^Q1M@A|z=1kO=VXKd6?$2LFH8cVHe~vg z&CK^(4^|_!=HWs=G`Wf*Z$WH#8v|$3+lQAY4QVm@9fDFel*(9cZzebBf6FM;<%`+N zb3n)!ynwm|itLXD24t}l!2SCgJo`jMaT#v{3-ZP_zONk|ENq#AF#@gR4;i*zo`8V; zMYo3>hF=9FGnYiHfVYgST#`SQW@3U9mWu36UmdE;GdkECSHcso+4#RlU&yP$YLb9ks%TC{)(6p0uZA(N&4M4hy#D}|*kGZjV{p#fR} zplud~X8&mJDiNnO7<48Puix5HU!{vel`!RD!f{VQ|p{OkI# zaiwo#nDo|7la|X}Y~?|X4@5j$7Ka&PSAQyp(OTn8E%Zx4gQI0oR=O8&qltVd$&Wix zI6{__2E!_4ru-OV!S)jbF~=^RWpf8FCX?TGpTfh7QnB3051)nzzWMr|s-?ud4PV!^ z;OpdCEiHpTXZ4jesr#I6kLPcMTI0TIZI{mi1^LO z>H4^7D;@RiE*is5IW)IFjw|eD%Ku*2Gpfx?6H~mC_t`_r1vCyS)D`Qw&``|68Z2h) zJYN6pCy#FB#EuGWZwQW;(GKQG^)~BZ@0Zd2Bnt`M>*@`)&Ttb1=LeJbor5{&!PJr| zSTrs4&IgSzF&ruA~qL5!*9*(csC5N^zUgx}TRE#>1BwmI0Z-({+e;V`9YqqCl#9)J=! zHPxti9rG&eX=dGOML6Aj>&D6&D@?zYKf*81L&RiGk^{uu8x z-ib9uj^jSim5?Imy73stNh8s*aQ`J5%7&hplfDHH|IGj`Hp=)h}hz0t)VaZ|91`z)>e~8uLFPADsU0NbuHj(M(U^(vzdV zwG(ak7jA?U<^O)M&;9<5KxSV2-G;rpS#_l*!J-chM#b9zByFt*AC33QJg8ZMhCwos06J_mv;8t{{+G z{pmB+9vmzrYH}Zq&(b*!2Q>}8Ze2RQ#`n(mATpi2Y4-W<3;vRU#ln~=k+eU zMJZM51_}HAEUfbsof7SPW?{;1}9TA*V;FACD0|<4}HrfB9rIAW2o`7o=WPe z$%Ahp-yP}0ApQ3ApKeuE=tZA{75BP)D|}-@#r0B~uZO$)Pc1c@fTSd?w{H=BKR5pK z;E92&R(3KqkPA=8Yn=~{cjjf%8KB4gmJ%wc)3d5R_O1C;Zir5sH6Q;IkDRkgk3b6X zQ2x?PJmyvA;it~T1G9v8)cF}UuX&8-&`X5Vv-EdNxDC={bei936wCzAJw7MQV0yk= z_D%JhrsON6WcAGzALZ9Ph@tXX`7>lL;V_au!;xJlCKeCav-6|=rag1PwvT4@iP)3) zw09Rfy`M^-P<8Nnfh4wtIHE~HIMX~AukC5c3dgp0<;(_AWerq?fba zJwp3}`{h9rIUgag)JA+Yb(;3x{}m$TZj^3o!4sISr~PtxxI0Ja6I%N zYZ4FkuohmW#KD+3UQ6TkGWjBO+l_F8)$u@TY^LSL%x`=VaHMzq_O~TsH)T30i(Jc~N;I~!Hm>1}=tZPP4?%jMD+u@zTQ`_DOlx{F#-?s(Y? z**)iD5W2gD3telPsf#pjG$gU<7*Mw`!DF9Fdo6!B4+=_T6nXx9qi>;T`I8%-o-}VG16lp=!kuS*a!zg&Eoje`awa?)~qY;*7iS! zoclU#ZWbiJj1@ej82F3PU|Vw>9$J1F*+Sq`Q&m+pHGK{tA|wB1D#RgSN9^AL7p&;^ z!IlVtRPK_Uv~U_;M<)%ALHorRrxJjSWBATMsw>zl^D)pW{QaMr0#xYHHYs8&DkKTA zM5@}grIM3)p5+FtUULV2<(e#>Zd z>4nt@JptbbE;$*{&O<}XS69Qq!s@Kx{rkY_63=x?8-~_-=e4G`RB(9A=(nx~gRDy* zvr;pycd;k2dWcc)bm_>a`+Ah#t<}Xka}#=_Lq2KBJt#&M8}P}PWDcsMNGv~-y?q_v zcW`cMo`##}v1`_$HsushPV_L#Tg)m8R|GK@3IPH8vbj@1QHy>@z^`9Q%!PmVvlag~ z9oK`-JF#qMt&Tr|^wwjl@8G?QALOPUj$3HubK4$mY^>G3B&Rf;XqwnQq*PaA3Gk;x zFm*Jd^JauZoV2w)>jT4juwT%!-FYNtq^4{I6Z+n8u7T#VFVirhZs3& z7l(lcl@tjwZ0UqaF9t-lizNO*gs4d7cr?@lQ+1@Phr3xP4b2q$r=u5A6J3Hh--kkw z(h>7fsaY%5QAUG+d%ewv4FerbJ8gaG{nv|nr}^ZbyAJe?Opzi?RJSy)!G7HI66Aa! zR*}?%=qFDh6V#M;+)bbFgfYGQKqk$JTwn6=>I1c0@5lZ0&X5i-6z|-8x9dCSpKqlE zDxXI0yfK(^AA4|spwBDji-!kk8cJ{xscx`a5p|kuYyY{^;6x)KOtIK44NJKuxO>RE zJK-g*tW8erebEx7P9V?vQGIjTFsdYYU6nmDhjQrYOWK^aEN3 z=FicYg`>SQom-icsWvR1(}#lbSX(QM{ZWr3TfCo#xM>Qwr z9Q%sbIcfW0yQVW4%oyKb@GSIC=QQ-A1YhkMtzqbAs>ScqKaVMrjiwr@l<#yk?5x!! zm3W3ls)NFDH6Hz8hX;fhnfc_vdH@hyuoNyfyVVvIedP@^astneBr+cDbU@imi!%Oy z8Ij_>+r+!f^a6Cr&ygircrtRIR20uo&t#&+QH4h*euV9a#5} z*A^ipLi}L7^tN!wQ#l?7(j<+YuX6NW>Za9c>TkZJ0*tD}U%VxvB`aJ@2 zM3Pf*XcaW(3gr)56Q`GWYutSdXUf4zwoiFyb)Cn=b?o|9%qD@b1p~_YL^ZWWI8}xK zeW%^0^0Y&MF6*tQ369JhO7*b*A$h((eE!Bg_-z6(-mI||4S-|e!}~9Xauk;OrK)$I zFDzml&|Veqi+-a}((?56^#QL7#aVc&I}(hR(r|n8rkRF^$1mz`5J_KL8cU66w5}iL zliu)P`b*0<8-WQgwVclAFc0v5$!g5^_sifLIn{^S{S}(v`?TpeJ6hVtm1eU`@}pMk ziCa;4IsU#W_&x}ezuVw$Ubw?C@M=s=f=jRPoN7_aai-N}$Yv%OcweQ{YwX&aAP5$1G2bk4jADlzyBzNZ}hujUm8}uRnUSG!fk0sW|%qfNZuDH+C7~08j z-U?BUqR5Z?M(P&RQt*!j6Ee2S$|iqYUqqdx_A?3d}Vw{qA&Iqrz;B{$JQ&k1%c*nEy&RAlTdF$t$>6@J9ma+;B3>!l#(J%U} za>~)?z6f}7)8yn;%qZ4wW_mhQKiXCq?mNCPNlObGmRm+gL`OHr4iF^JK}h)O+6qPd zG1FI9ve}4@frp!64#}9$1;mxPqbnXxExA_`1fASGd`y?MnQAM)F)>IZ7aW#f^f2(R z?UYlOQ?+YiOhNc}khIibkT?n4X5qUsp8NY1!}ovEHIk(&8Zr zMnj|P_&6}_c4xD}Zg+%DWrxmP_u#i15cXtDxz%VLK1+r7xbn{4R4Arho*(MzK#^d+ zzEsZ`%PT4Z9#W6{Tb}=n@!j7sYUm6gm|BWq);6e2WtPiwoK^-qHm=cIZpcV(s%&dI%D=i0^o=94qZU6YA!&?Lx;!gsjlWAv6${jp(yN*G6ziXbA6J z?<}NeQCkqaXMtvdfrxwUKE@buol31NwrTq?ox#Bhd8eJcchZbjXz#KA8Yew+7kqs4 z=SJ^ps8ZRuYLzgOM@2*6<;y=a)fWFw#0bX^ws8U+Sy`1O&(<~{h;H6UZZJW`p`RO1 z&1gr6o2{-fZg6)Vm_J?fuCI+a=qaP@h0-68pGCu^I52L!4jfLt?=^vp_-Jb2A-JwU zlf|R)F*u00?*460uw1!`r033p1idq6!pY^dAY=7KjTY?FfRg!g|8Yx5E;&hL7YmMC z1`1m~{`Qq*8`~bkAn$>%W|FMsfZ72k^ZH@Uoexg$<~sfYKz#WH zU6>E8e>c-up17t6FEpnwq0G%w|4uK}g_S%p=Lbz6oHy<97`k+^+_?Ydce}BvAV@f( ztA=-GPzd9{Ff{!H=_03Z2l!||fBp;-tnT03Sru9Fx+ea!850rD@qK=L5xH%#t>s0> z>+SuBHJU!CXxB^wiz+)a9S$;-t2G=NG?eeql_d=5@gdedXk;`OWzPACQTa<{B8xPk z(~Ly`A;J5f{SdX69rHj3e!Ax+sg4F(I=Z*w5oXFoTvWO|y{=PrOV~^3`Iz5J$AZaG zF;;=MH@H6Li9QY3GIDFg6p|3U_u5GY(gdfD;YW=AXCMAur&ExSVHzsh?L&+#49wY# zEw`u1>P8$<;wCd&Nx$EIU_bGYcD>iy5f`x&$Jas-{-MJ8Vgk41gZ_V^nxyV{SPuqS zz`!pRL#S8glgG`Ejz!j1502u8^3c>b?kvq-As8s$g~JcrKW`PN9GIZIydFU^kF5`< z8O$w%cZBNI78VESGscWZCFtJIOV{8yDhSt5=wj+sI=-zx8B)*nU}R!?BPzPGvhtsG zZU_l1xqT@WlOVqzS;}xwfVHV-v@e5N@6;CA`)8d;R;h>Hjdx|a%utt-Txcc6O7a9y zh9U+RdbBor8A~Dkh^fO;U-7C|e$~$)!?uQz#n_sN0b$Q?%DUsb2c*1Lx&C;-V8ddh zWyQ-@En8Pf3pe4!xC<{vMsRUsHcA_L_S)CVYW`CE@S6!zX?{RVn8mCfrk!a{k)Y+& z3ltQTe`lrSIhd6q@GVe!dCKG7M7H>-k#SK%T`MZ6Y>(?;fVL}fmuxkpQbh5zpe}EN zGN$c3qy_jqAz{Y*7yC_iJv&0H_l59FDxUARO8Ol&$jY=z4`c(TF?kXnV?mK->N)R+ zt&XK4#PHZ?APBWG!}<51kbb#^oW}g(qMnqLR3E{ce=5~iq8yu2+u!_ND@fzMRa2u` z1dT&2i9fLB{P^MjWDApI#mOB)sd=PGOEh_!aC!4QiSI7f}P#`#3T!B)4-t$f-XO3G$RCEm^2Z9!#7U< z{6WLPIot}8Oqy$1MU|2>Gh+zp+;RP!`%39Q{TZ**7j;?T=gjxvQtFKRtDf5zuZ#;zT29N`niKxn+rjn@TqJ2}RIwA;3f2bX$S}VMKd{hI zP>{{pd8+reH+h^DW(>J;>yA5!#4+-87p#cI#EZwF+2fbn<#Q_T9U zf#&YG8tt+%_xEx>RJKh#D@s)$VXgYhPbd_t{r9)P71C;fJ?K9}90z|zs|9L9URU(L zvqH22)whvZ+J%55I_aH*%*3$M_t=kjSQA%sJ{D~4{YdRhFB7(0PAh+0a{xf(rx*un z*mKkhqU6L=dD=WOt!tOvg7ICampi#m@8~UT&MUOWho4IF5>2J)J76 z#v?m4G#+oveJ~;B*^ZWKo60U>6(_=fmJHy_P zq%mw6D_yGpg>_tEGp~n;Gp(YuE-e>YD;?@7Uhw@LMg}WdTwhgs1@rEB2$MS;9Mmu~ zl(jE#a=a2IB$T2SA!lHE$>&9Bs?!+BLz4E`neNQkT7v;MeXxRf#zT|s4bA9iooe#P zCC0ErbVbMs(s%Fl{3#MQ`9n?(nfjpu{05&2Y#9wPsrsw>a+PYrdQuiafB2z72fH?g zWO5(z+)P^XUq^PNARb z)-Pufq4>oIB7}8U7(DdKw5Q-tg6_m(m|dT zV^J3_9kHDWF7mCI7$+5Cr;HE1QvSSlm@ zG!ECcURpW-W{2~Rs<`x3u#x$AoZAuSt`|K67)HUag&mOMAg}SOZz%{?36ciDzg18u zlG~p@Lpgu7H!s^#_pql(N(2@$mm*hXDypdX5f6MQ;_dw?eQxKeC1^PTB+qFn3gQh6 z4GlY1LCP@bs$cCV&R0HE#%;F0TDAI$ zkTOmjo_5fr9)Sim@BgNtto)|QSJ8C1!XP33-LAhQ)l&W}(Xv?7U>k==;Na~`)6)uj zV^m4fl$Sq7@(#;+AVsAK$)J*yf_}XNS4R>cF+ro8Z6)LPhf`F$c0Jf;cR@!-NpIH+VdHN`{B0#lE9#7A4;#Hy{lZ38b${Dvgn-^j3?{u&z``Z-g{xE!$*UsG50EoaeJW-)`x|3M`_yl}z5 zLKzL*-Ez^>B~|uP{EPD-cQ1=y}-0i>?uz#-J1N2v)jhA zNPBGzUh|I>xD<{p3Ox3#kJZoUzI<_2waQBJjtc+ zHBYsT!NMY){X&@`FQcL10(#_no>xX80_Ag{gqHkz)Su6?q-Ga2734pM4n09ym)cvS zbymW^QAK*_n6c55u_>@SyLyNUmOkY?1z+!jZzJmNqQkNGE-tEk9wkC7<`KKsLI{t4%leQxaxBRX zb}?)A)yz2RnkT$aB3N>~*i{tJoZizJ!YL?#ywi72e^tBa96fDqC~_8d8hnSd@sJN4 z23l<=%)Iq)IRCDGP@;Ral=f_+$j(_Lxv~Ks@)LWgdVLF9)+g=%heA~T6r%62TuF9L z%6Rsyv>-iOjKI*|UjdxUaCg*?LHhLMYI`wKVk{Hx!`S5(!*4m{xSa|j53dV0xDVyx zVl20noL)xx3Ak+l%ULyp(<2_2ZoD1ge>d6;k<@gTb#DD!32HlM89h65M+c$?l(iUfDn&3=ain zk;5$3%ZTS1F|UH`Vq#)|OFh(@?G;D>1vw#7UeXkzo(pzp&q#x^WSyoC) zg=_`Q`wOFxCp|Zbtb?b}p?So9oXO{_Trh+s!Hr-r z+98(wt%tcr4@T7)KG#eU*XKxbTw|NLAPuY6oR^QRg^^QlcVx3yAWYWP!Z>cpVOW2! z#wEn=Os%1RV#hhSsTq_BRDUnP0#KKE1j=e^y4B`{6FFnsK*U4AM+G)v9YX7JmXOPT zv8_c-F!$)mmWlpYnO0v?PyF21M6CkP5}Im3XBTu)NpkSumw|)uxRM0)+Yv#+PFN~7 z09GYv053NXpN%!-MOSmXO|$HnjHU2 zqOSib)y0HDY*QW2zO6%wDJlKqp9^}#LLFT?nkUywR$W&}ag%Y7>~^DY<3iwuSkNWrKQoavHxa{ zfEXqqHUx{<956_SQ3|;J4eRS;;aC0_?PK~jPWg53E#ThEr1l&Lx0R#h1q9dBhA$gJ zb&fXs1#S|%0!NFRH@R+yvrC*xw+@;Ag}f<+NnKR;tDo-zmc6hltM2l8Cma4}BmM3c z2b^2_ziB}8yKnn@d%(R5=;v!757+nk+a$*=0P@tIt1j&=V*2e%g*k@oKjs#t#Y**S zUpq5T991M%Ex?9Roj1qyO26 z&N_1jqM5%09t1`8V9Ur_4ikVw6S2_I+Yy2P5R`<0Z913*A^4QBL6p;pLX^?JdHnpX@ySri2 zY+?g<;rXBQo^yWh{d({Ev}3I`=bEwRnBy7ac}igq2=mv-p8_;2Oy4c1cdLHSWreEq z6h`S0(#4y7dq(!3jY9ZT(m*Zg)AY|G4ls;z^U3Ql&2wulR}G|mfC$#bt$T5L&8{fK z@6)UmglIHTEgX{`e?v`7we7!PW6Mg{2h`Z^VBM;zq&tha@cFz;ZespoM~gf4{ir>PDa&D8to&*W!B6Ac^dKm&38 zYLAWt+p_^_e}?{n2dl0TyX(QGo4g>x_XwMmZ^r+C-qw_H2THmwylTaA5>e*wH~Kr? zejory0QEVhgdK}6fbKofO*#d!VIxTj!3|o2Equ>0dEXsv-Ap0*{e$(^GfD$8s8U{0 zH}UU&rX|q4j#$q%p`j^{(Q8u3!%|iK96ci?wVyx~fKpAz!rCL-FDq>bU5$Opv`56p zAhn;Ju)hujCLv9#KQiS)@;fOE#9*@>ELwg1{(3G5FEhE|&fEH?sK(=@y8maZ93#_J z&H$A8A5Y(KJwe66o0bQ_Jim`hGTIuF;HDrIbejF-gRzN8^}Ir>US2whqp8#Zqw{~F zq-K0Ze|FBj8`A}51OyEufBSo|{RM49wke7Nm#*h~V7&_y0Af4V?#?yH8sw<1f#fD^ zEi*Jui$3G8Gj&h&`vp?#FJGSb(=?+P8asYNj%F}DG2_(bn_Z5g_qE9+ z@*ep$kBsxD-_6Rh+?J6z`gpq_BQ;|+3J!JD>_mt>`9MfS6ueg%m6G!M^=mJHqvYGS zCrFB_s;>dIeSlr%GmjL*i^Cz_Xz$Ais((U`W$+(k|I4NIdzBSP+v`kCtQwM9_)*_e z`Vv+DYbj^Xny=Nh8?v878BJE$w`wyN`{!}9-ppQBXa%LEkNr$*1J;kNgy<2u!f(93 zd^QOyyQ%dIwB=AzML~KIJDv-~8~pJ#OU+aEWTMj#{R_a7A~{rwMEAN6zp9{LH32sL z2HfL=^^h%UB225Jt-;hR%OilQuZvjV!R_;ow74!5uP0nSBB(!N19{lol6zM0dhSd~ ze zx$!ZHH;r=i1va$q5fVbDcK_LBRRMu)tQ!+7T$bVO#(0m)NB@M!#n4_7Af7pztGKQ& zBBG?u=(7ZQB=fBo)RmepP_Y6Eq3D+^Xt9NH!A_7DryM!WpU?fcGBA}DH_95P+gaAb zz-`Pn2#ewQ+f4vugT@;7Ar&+8qA$M$^~n!4spP{HOSk*B>7~*wQ>6T2@|v=^0^KC* zVw-$5t{#S-e_pVuDC+Y{BstI~-kbhbxYv!g{t{R5DaNOBgz#&-1P*l+1pAb;;vQP8 zR!0+MaZ4z{r2YoxgSV4d{cn*Lhvt`jF#4RFL)#qcEBKLGaiwuuWUyadG6xasI8-mt{SfL0o}gC=rA2peHjV#%1{F0mb~>iJ62IvsEhf73dhS;la~Q^TXy zjmpWVPSuo>B#=M4)`8riWmT}g>g z$^4s3PG`CY(8;UX;4Ec}25|#pZ3%8?aftEk%sy&21X04j2H!(HlCG@1ZZ(FWdYzB` zP{(|}cLmMa=jpvNevBkH!gAb2D2hrs5iI>N>zNNgM+Oj7!CpNh^X>d+IQ?yUQp(I+ zArfP?q&2NQW~8s<82ag(nOW*;C!;o^aDa03>0LebFj%fvB`!ifY5CYpXK@*bEXW4H z3sL|te`$GANtrL*BN^mPkgWJY|Bych$WHg=cNT+8c2w@G+R{vhlkg;ni}Aii!aL zp0so?wlLz8k&z<+Y6JG6mAQEsz#$DJRRCKdQbCCa%P<&MeLm{B#emt`PG299PMoz% zw=2(`2Cy&-4+iONF3O;f#n=Pfs&oozvF4a}o#7+^WY49A0XYmieGGaW5<;)Gv!L_h#S<~rLP@)?PrqT|h#XRX`IaQ|a`fgx5Z<+K%PkoD z!}>%BYHHS;$j5Kp+CXPE_@+}wR~MkRtpmiT(JT0k`deBk0Z6x6;R$gUz(-5{a>9uT zX_w;(d=|Nd^nE5`2o?9KqrNG1UU0q`vaqe1&Uh{@i7*u?&30>j!)*7milZ#2@rkh0 zwjw~Ytsywu5lX=CwEZ4TB_5Vf(SY&fF$qaBkf6Y0Entq1P)EyGe+sKc`^xVp;+`J9 zF45pUg-HkUZj)EIcb$xt09PGuo292Mg2ATTRI6M2e-4Q8+?byE0JH@_h6Qe|&IcEQ zr%wQBnaiadJ$omob~|T3%YbD)&*e>3Kk4arXmdTmLEx{BZQO(I@y92KaQ&^+xpo_y zu?z@)6z`4rUVxky3zlW`Z_nsrT5W9%cMp%jM9#p5n73S9s?Kyp0RbqkbVcte^3Ny$ zeR36+!+FT*TBLA%-^Rp@CBWlBk17aL3{^dvnZ7!t(@(oCI`i-ry_c!9bx+=X#(7tX ziAf0}bA&=y6N_xmxz)zvVE%^yL(To&ZQq{1MtF>phAEWaV}6hFtPWX~=d5muY}+0! ze?F*r&-Xb|k-k?B8uaEkc&kzF91u7zgll~FS(c95_6O2Lh1`xPrqG1VhciaKj{s74 zX73kg4|4F0GTZinTG^vR;^H3r&HTQ3=%<7V{KGjK>3);%3T-MHts-H4L3CR?wMRCE z8n-1SMs-4$K>jxn9;8$t(ZG5J`1ROpJ=!UF~v3gCw=c=Q2Cs!a|a-o(Er&RUTz{RWzoq6h(B1CoKNnns22V zffwB%0G41iMA>6_AuzF2nVz`%&4vami- z`Q-7Lh!RyKJkNzR@wKau@4l{J+VDWRidHKWCwQoTU?I=x`s66*ZLPAt`A%ZwUPVS+ zmY}O-6vbNifG$roRSXAbHuahX5w|_|Rn;vaiD-v^hOGp-K=P|HiS_Mip=o;0wsUU= z2;^OTXG!Btr1e6VpN2SRTPwlc-8vbL+}>?bmI0A)q1;!x=h*tSOt6vri?H3*+l<8O z5pAey0-HXo9e(%8_U^7Ubu^G!g+(reD5(Vq3p0e;1_~5I8bzU7<#{Baf6=ZK zovxapzG<*zGGvB!TP!yLH~F=WkMY__EZb`M&SD$I@t|Vv$BTxJ``U8wnckR5pm3Vr zak2;Ik~e$-(76A&sIIH43-IzQC@A>)`eI{8qGA#Q!diUq-mPL4UZe8lJyzwJPto!m z-ybLdMz=@T`25UQdhO$0f%X}Gfn!wouQ=@~e)~KzFddabc(pyP$!GYg>yLH4P~704 z?)mB3FPYme*NzZgT4q{XoeYT&n^dgTb3fgDr!B3GWGc_M5*FkmhX$H%WZHwt8_q#2 zR&3gNKdT79v8m}`u#4%PkE!WOa6<65W^W?)WMq?&ReGit)sVh60TT$cJLl!*UXU83 z<0Z6jj5vpUZ9Pi1BEw2r1(-Hm$|eBqE(nU6xE-*-0*pL>t~|i2+Xw_iRm*Ufwo_>U z!OzP!A3g)mG+&^7*3TIs>_qvig;X8T0WRBcy};gBUw*@3eNv<8`{eHUNY6ujHFk&K z^nSPQ;sS*X0!#L~fOXi32i^jrdV#M=tbL}u2Pi-xL$cH-Z(MhrH^+Wkr)Y8K zjuJg+do9vDam|l(a(b2SrO_vzZDLv`gDtjhaF{J>Y-}h8cIaHg*|FSv5v4OU*CR=% zwv;m0G1bx{sm;ExEi<^VIM9bnZ5@2+)7~iq0)aTj)L(UN2q>qigz^(dU5#dj%2ovj z5nqRsjhHXgZ|{N6xDIfl80#>|gc=mU0-NLAi}kDU(b&U276IudsWWc>2WAo=<7{aa z0Bez!?49N>$CB$zNQ{Khyl=NO%QsSgbTO0mhoE-w ze&of~r2~~SL-Qr$uXQBbsSHhNuT2)}3Oi?GhgjN8gbV8cRWBgYA=m$j8z=L5ZKaMS zkB-pEX3Q`e&M8bF$+>vmVe#~Lx8z1><0&>(9S{xTTFt1tQH$c9Q^_bz9rBW_EIJ5q z1tAe*wvg^-5wPL8rsf(8;xX|roSuwUpcr;wXb!Heo9#fZ<{d=TYb=-Q#t8~HVvF+( zgDGU9Qc&b{n%u$E1gXIS9VOC3QhoSOWm3Fb(!L~@rH2GJaIZwNnsKNE2T7FrBNG#- znQPY*0g1tE`V^(>&FA}HU)i>_%|lOIA4t%NF+@!=7JJ-$DBRlUZQV86>6sicV7YzW zUD_Tt)%z9&Vqj|Mh>JUN2i6J6fQaYq!l58+f+yKaR+z7FcA?!mGB3*K>w7S`Dc-%t z<;)Xt;*#`{9kwwt#`1{iG<|TP=q`r#m0((9WrIfykYT)LXPZ&e`di6=ax1I!&0=Wi z5Uw|Iz3P#Rt*O8!e&azhbT$B}7E<_EGS_@pV-Co*OhJ|6d8|UYPV3LcGgbk}dukRB zhUie$zLy1yUsr^+kAcOK`M{wyfXiNJso4H^Q{b=n%*uzHTNVwj4mO1z7DoFGmg`p? zsi?8MYe@Hc^R0>b$aqae@$P4vQh?si%^#$t5Jq62yl>0wBHbm`9%|ufhNMx(zrZ;@ z^KVRQK01}g4VIF})bV#~Z3o0Pz{bUP$`r~@DRUp)A%vB<^4`Ic3QM_($(3ctG&m~z zw)t}KP1iYlBeTLc`r2I;)mBpxK5~ilYw9}8Jv{?C!Po1%vVD$2v17mH*Vj{+)8Y+~ z(XbaPnuTg@*)wgXBNI*>BIhsnOzx#z>P;f`BOwiI^^#!lt=7=ln?LZ+0J~ZJa|QVT zt!$VN_eV?9lL~)P95GvrK{#SItAA!5g`Caq zQo-T10(2!6;wmV+cruot7x|t72(oEiyWPbT;KR$PU+F2RmKYG?!_##_nt&a~=(~9z zR#9?%4U+U=e>2_#_na%p>q~Y2KGt|ul_;n6a^ym#GOJQ72ji}xVl{o87t}@`cvwPH z@bFeB#0D1PY8l3Uh9+g|{z7ZvgPAM^g)^HLV}J+Kt8QHVn9YDGsGk7y##86h8pj2Y z7w%V&0*puef}(WH@;7U;XE}!O_LH;Ow=ly3{kUXV<0%;VmL|8w%D$FY6Jq`x*=s5y z{9u34RC|f=d+)d?AtSQl!W-4xi~N~Pj;DaJwp^)%Mo~8<3J_3DV74?}{2_dhNdssW zp8%5=DZHI9rZ287lF(w$oM4XGjAJ7f5hf|oaH$TQg87Zi)vumHXr*-&cke{{ZbiQ4 zKWr4MY^e#Goil7*RUO@$yM&CID7n|KGHOOPdNB;bxs;PU2BOyHxj*Po$vr&JgB`u5 z+jJ|FtVZg~Tdn!=q@e7?NMkZ=`o+;fkKo(U-@9sFUMq2xW@>#WtrBKsCi!-8Q^TLY znj=e3j2k)9dVny4BXq!S;+h-FYxs_M%N}WNJ#~0V)8)VIGw1jSrv#g%1|jVxR|Q+R zIviCiaJbsZaZG$W6Azl5MYXND07U;T25a73Is-SdLp7Su#EROmf&P9g!-#tt_6|~K z4J~KWrapWvP!sHPGO67)h9MR%u$VsUoK2==+<%OF%j&F+Nn}<+2j4o zoF(>{?68?@6Yi)0&8;h4VP@T7YPZ&-Bj<)yvRk{MeAY$mBux^vsg5!RRIms#$UuGk z>Zfc0G!6?VmCsksMn=<9iYAedFU;*-{dZGSaXg{c_>GNCKsn6PK+oWWwLvzJ-05nt zBxLD}D)ZpL(A3D=H=Hat`VxviR49HB6DB4R?!@`}#K$C3t{uAxka9XY+IUF;BQNv~ zDfKwW?s7&lY;n}QZ92qC+-0t&bZWVoGrScb-WJ&OaqZxAJ*eUyv(A#V31_7doL;R> z<4?-0Otdnzl~v+D_huWc8*3l^)XE6Ad1jB7A}=$<egM^(}p=5k#B4tDPEuAnqNzIoa+H>Hxd8H;b zl$0)^_jX3X+fBKBSiS;Ht$nBXjg>nT310lh2ZK*R9Navt-3%1J_Dc8uYFp}oXr*kYi*|0ly*$M zNYrvW!V@fi%v#Okiq1|0s0W2;dK#eN@M-fFU7W1Cejc0BNST}FneI#tT3`M7`zJ4m zvD>RX$Atv<@R@G>-9<}T3wJ3vHrW%N5QICg*L?A%FpCC{8i%OHVQ1I0)wycx*2#FA zyf!PO$soQ~$O{eUcs+u=)}ySkZ*}$5fX;{tgbsyl8hpua~&LthVUs{22netI}*vg-+bze5G@4MnTZ%iv^542tBld$(d-}g$GX_r+3yduIgk1* zbY9c_3TvmU?83hGahzs~lgeogR7e9Tc?BZ88RHlRevA7eLjGRd-sqOt|JJyNz~7YhRy1xln4X8< zeJWnf|GSqa1rVN^FY{tP6ZXb+7hmx7d96TQTZnJo>*FyH$l)^~5%<-&ITQ&bJtX-m z8g^}$F8_2lqo!!_LUX7YOI=?y7wfQt)q6evQrxC)HzvPwDNUHu1rz>`6%bV%Aoh%! z3zaCnp-tBvcYj{%eD}i$O<1dgrOS-=WfVlFj5GZ^>E(WJ)0Gm2r##W53*t+ZupoW7hCq6{c4D8!g{#iM6*eQ zLp1F%h^gD`ep_}sd*zrcACSs?oZ9)vPtyF&WsFoG!GP7e?LY~_W^sO-xyLFtj)8`z zqpagbX6p8M!R!{Vs6E&-a$y61iZ$_uT22<+UP;K~ecZVeUu&@*9Uoon^TeVvwc0=l zZ2W1jb~iGWfHg(G(yKI82xsKd5%;rjvB{6)99+~7S}Q+}jOK8x zBerFOq}9em$rm>B)s8+``}|7wI(+c+p9yr5(=U&2gTfQQ^X%1l9rLb8CO3F%3!+I1 zh(DE&a4dGTzFlB1T&s|Sdb{1C+q#wcK>W0@`cx9)zj=Ev~T zt-r=3x#{@Tk-3P^mppZUy^zf|=cKXtN~zvgXUOX8X$KNDvel5mEx&yq0~;AsUQ=_{ zdC#&G@kx`P;d_mv4gOXhQ)ly0O5k(z78XmQSxoX_(c7n{STOZ@{vodl^Xv8Z!etQ) z*JJ_&CMJil4OnrW%8E@bFvKi?3Epf72Byc0^uBZb-j^>88Ru8z2IH>hX5_$N<2tYP z0lG|V(B^_W*WO1I&y-MsLgICM&g+k4wZ`kFS==jG_$uFo#N+y3utw3N@}IgnbM`nN zj7Dhl*07vy%CO_i)L3sAs$RpBjk^>alTfZ*_c+aAt@j7hu9qe*A0TKGE86)Bb35h+ zZ7l2f*$>Yac0Qom=fz2KE|>T$xECaGUf@?1s$i34vfJda@#_3-WR@*#p~hl7qg401 zSCV4D3Lq4e@d0=cdG}*w_AVLeNtJSrfz6E^6O34Z<}2k}u{Fp+)kWkG>fjf(4{nb} zF3>@9S>FJY^>hHrruNZYaoxtu3mhsNilJD_g zjDK43sz-CUeIi)`>@bqptukMDmQrQ?p@$D6W(@23?B&5h`*fSeq*sM6er<)_Cvx3t zVjdN-ai$;fDaE$b*ce2lKOUndaQ+lG5D*;q^iYi_S;v z9d@_Q)?sKZE6aU8iipJsM(_z6=k;u7nVR}Dk~TxmKR-2@9KAjmif3LQ%lJs`u_GF` zwFx%miEy_~@|y1qz|)8gZT$k^{h`=LStq&>b&Pm_^j&HGq%=qgV=!g2K97prZl~Hg z{#TK*PnPEP4N=%v8@#pF`*%FOE+IQVZciZzVF~P?bLP_FYn5veTzWI97;BIj31kA7 zAou#R9tFX=x9;u+;rQ^hs<+14`_3B%o_O@W8O<~6j?9$$6VaMmWgf%~v?)8){gqvX z5owjyLhl;CX`gQI#QVi%jaQ_%cI3xVGI>kD5)mTO;PzU}JJEFeU6gQvS6LjT0u5Tn z#i~47-;v%}Kk0!2nP?vT_VDdUdOw~^1pMt}Y3kHG+2&WTwz$Ygt9 ze80Eu0L=4>s=j9gqwQB-m7OgYA({*{hDyQf3+*`s`VtebcUSM_E@LqUJMtpfU2Ugk z=EH)b*CN0h3BvSWO~{(uql1FBgx>tAo#zVwYLInt<9=0e_wEow zEvoK<10BM>mJsLK>j3!{wIDINo2%3`?j# zJ}IAAxK2KiX(39Y}s_FdcZHKHXa4p|0_8#T!O2o5 z=MIDR;NVq_sQwm*1BBviT^h8y!-Htnpoxr|V3sZ27BYJ&4wfI7t2?1j!@;S>vh2Y8 zY}P9b`CPrWb^rNf@yIhWCWwA_(*$&4wa_JSKRD41Hk|2dgI#;)b8F;6wj@$*Twga9 zYmL;cbsy{z#3FJu?KMYK#W-?bJL!)*R5ygs^omVLdqUyB1m(BgM9>8%&L>@X)15m= zr`_J@fjHh)(Sp3K4!v(`WC?jrPqLnXR&JAdUP-X8D5T!L(lITR`x51`Lxp#hWopItv8Sw=_GuL41x77QmZ*Q-9ZcDg2$Z%@-j_1N zD$O26t@Mseb)scDpbc%vyOW)QsL~~E4>$LWjl|o@<{Q-LDM64dPf;{0 zT+qeQV(Q~y9oDTY6qMxMlc1pNfV@c3I-FY(?YV5VJllh$8&hfldC37vK)06%TY^NX z7cVl`KPae}U#J0kvvYo$H>k^EtR**hwmr)J{%wH*UZ14i=bK4nzDNKwLgBXgrBS?L zytck#IwZFxxg({p8eJLO-MhHZ){_*}A?TBB*HX*QDd}~=#Zo&wJ6Q6i=wL}$_Ud{| z5X^P9H&JAUt(FqdMYdS)1zYV%dCb?7=&!GMZ=1>@D|0`RSxSUIsTd9%*+}Om*Q#T5mXV>&Y4q z|32+rnC~_Cm?!8P z_Molx#Hxd+LSKVxnaO5QaF83~gMZSb6Ye9VWnEFAD3(TnSvPl8J#|`6j9N;Y1?iH> z-EqV2M;fVhNNO#D-AcB-R*;;U>HCyaaq^md^lw zUq4X2DH&73ZGKK3%Op3GVC_v&eA6>glEbwv)-+&Gc2Y9kA7=f`==ysntF2HI>hlx( zn&LFa$4Ku>zO(=1C^Nq%balfdT*Cr?4oS;;4ky5f6_vV#OMHEfdD#g z21L6%i2^_G@&iTZOWNAP0RB)wgWhx~Ej2Mwb8G-`r{+TepH+qfpn(bS(K@@j0@CnU ztNg$^7Y;PBUtw=wpLT`uvw!`f;eQD@q!p=vtCpQ9njg?jBfxEUbp2upxZ5HTP?DR< z?y(>fQ&Da*@UJ4z&bSluvTlqdHINI$2IS`Ne2+Z<;#=P?JfYtNIAhg{*H=A(ESu_@ z2mEUhKp!76*2e%9#3WlW$U6YD9+UIq0Yyn#)&l|INY1!lJ)71xHma>>DrOT)HwRNm zh>5kvO8gATguLp!Z!Q?|frL$k6kc|qD6M259!gR8n9%6(I<}FRm%;pr7q=zAyN8AO zn)mnUgCGgOae8*Rq)+hz2>7C*p=t83`M|QWy&VJ$c+0r-bURDS5dD&BAP@LUT%4NR z?WkxZKT=~wpdP<9Db-kmpyzKM*69SinK`U?d=V6aB>1#9Qbkk z?L#+lTUc1&;20GH)jq_E>?+!!1^&SR9I_ABWjy-7-x0X@;UGo=9s@YuBUAhpT}3iS z0($)6!1Vj4TL1rVl5q-Cu&}o7UprpBbaQDscSU2Ji6<@`0$<|IwQNubst9cA zbvl~vlHd%rD)1rGCU;F1r5_i@h;8iR0n8?1lq!p{T<5+`7;DYs1&mX}8o#2~6%EO+ z7NZ3yVwBafB;!bPzsaAU8>QBqxu!Uw#czBGO(MnzJz111$x;w;2@ZxW(iJ7|-{Q_I1w zSUli`n3&?+)#jC{ciBF=WuEA3m+?(k^wcb~))LzCkVUVZH~AysxH*t6bg+jSVLG3* z7f5h_e3+GFMT+#^`(gHsH^PHr=!Q}R+&4$h_j(wHx@xTYOMHD`!&xcOBdI;@i9|#q z_C0Cat%#Jfv$Nu21iE~C_G(pC)!A9q<}KDv-~U)w_*UkoyKlG_Di`!JO{;qc~h+gPsuW z?6?Q4R?LC$%(C+UfoQX>O^xCBuPOWEXI1^h4kS7|CXbNvJ%Rb`w=SEjHOX0%e1FT; zff1jY!UFomXH8UNns!{jSZf04Uoo$`%+!=d@5#!KarmiBSxe|lvso>a0j&(2u z!-<Ig1H2UTx%yK&+?%~=>Jw%6i5;d zyKK;x{1F_GL%K9M+uJ(X;d>pubULx{}NGp;5Z?1@rCP8vN8g3{MvJQg!n%o@`AcC=M;wSlDi%y(tVt=DSqw)=6k|@>XS$ zE$dJ3-p4Z;;OnR+GJv;eR6cU&P~S)jNx3m1)393}=Hub%)Z{ZaU+I+DHQ7<1^1AfM z8ETCyVl`FkeaU*KR{sYwW=>?pW;A#;8&~c*H>BZUN3%2dsEA{UWyB8cu<;5-^Uj%E zttl$8txI2iw&G@a?Xqe#Zmi2$d7LO-AgaXfG;asgNr;>CovVValHK2|RD*PPi3Ov# z_!;c2{|&F2hbCZ$yaD2bu4VA%ld%a2a8D_?xi=@{f}EMQ_><|!ewfTL6B%{*^DoU5 zc}ikb9Q>p*@>Ew)Ey3Prx4uI_ZfCibOEiC93B$lv&AUY(J1Q@|Ot-Hmm>zqlK=9-T z0z-*BeQf&0gPdpqc#EYZ4Ao zE6Ej!#yLo-TQyLbV(&DKG|w|P-ixHRbmk1?(r8Mx!!Mn$y@~wc_p6Mia9J;|;$=&d z=oDOczd!fR>pOc7-J$zuCQ|ROQ??6D4kO@=7kINT$hruV&rK9yCXpi;tV@lqd$W)g z-DHNl@TBK)jmIcG3iW%MlRU_grl|?H6>l}DHPi~fHbhZEcq|(XC+wCYi1G``F9)=8 z?{c~aw*n`i zwAipMRmPh?Pt~H`lp-`rBubQxo{1>S-xoB9rxRFzkE>AnsKEF|ImNZuyE#;|GrWN1PLDFZGi9JrmPM zM*Hh6EZQ!wgS^gUsiW9C3zb#A^yg>w!fjq%P$aWoY`1Gox1~NJ!P@~xO19E zG|7RDADfK8=kyD>lX_+-f%*Q}>2f1Mlh4lQ1EEn5HX9t{nCY}~g=m_aQldAm;A;a! zA~4&l!+@v%R#C}vQ9!pf8W5+bGu_C3w&p_C(1o|&m8$xR*9q@UCn0~`nT%~fj#;Ga z#*!7S?`T?>tai;oqv_2`p$?#U_wM<_%2vo*hn-d>on5So0>`E;RXj*LU)DDXsi=!7 zB_?QdNKa9^*d^ALd$}ddU&8F@9$i)#y!|q?hSt@SxL(tn?r$-W z=R-ABFnp$({Y88cEPM?|B|0xApyRheYh$$Dc%${}`N?o`))hw87VrJ9x`hkh*vgU^ zmS#(w#M%==P+VC9%QPWg^K_!5#bJ18t4v>SYP0x1Gl~1umT&W-1Q-T4?moQ8upTx@ zP}P=&a)U}K6;9l~U{Q zrwy_daJ+CJ~g&?ufhJ20-em83t9{C+`Y z1{n8fXr5+UzeIm}b`o%OenbSEhrEqXMIXmfT>buqF&+=am9rzCdN5~zld&FDs*4g9 zT#;UT;>uuD6xY>T%wU57^X&=whe7%Pi%HOqS3K^bTvO%XPk`PxmXmoGb_}? zqopN?FYb1)u(;U>SeyMhM?cm`!J;88-s{Q|Pmny79bzJO7XEzP^op_G$22V+>j2!5 zKH2`fu{!9if1z~V+i7ztRofMIwY7u`5!u*8tlJ3_E##OfztG>RW|P!umxq?7qX&qL zp2)oraGIn7u;ki3VGj`*U#qV8HXw92n9b4nVp0s7Um6XFoj`jo1^%FV@=|(yvm#b1 zj&q7|XV2o`#=Udv)OSVC_3+;Q25UgX>s;j8C&x!wl&NC@&(I>mGDr2}54MT&HzQ@M z50*;XUrS}*IjyoCeq0Ocr3M+S!=O}j*lPWEJ_c}BF;s3W%XM>ey=5cuSQ+riRvxP` zdDnSi2=3gw`t}{oCr`L^>n+N{V+1?$UMQ7O>U-atJjKE3i8z?E+1}qe+#0CmV(ORk zCA?W~Y2qJbLDSJjIC`9nC2O#iXrHvL>?whrw(bN$h0=0-)Agjj4l?*&{5)NTG3kwx zZYgP+@4+PZ2xnLwxA-JCE%*vd9rnB-i8q&&U|6h6K1F${D8yu=+*uWY**ZS%ykSSu z?;I4QC)Dh?sVDOJ(|^p>rAvG?Isz$2%Y!(%SA)CO8Tim@h&$$ z6$*}RQ%w}cTQGSM04x_Uo!J$H%HAthGwgQSbi5pD?XR0&bB+8)`cbfm9DXlteR<5w zs$s>)tG$P)uwv5S^jzq;54V#5qbS5Bh+L6JHH2a-QRAdGykgB`*FhKl?X~(FC0SSC zwgD^oO@ruPD@49%ht(G;pM66PO*6?dzduZ$t*|6Me6J+MrnC37cEPODu_6Kik$!6@ zwZx{u*-04VGpZR?dzscEQ6|tWE%T8}p6@Cv_#Wen*WrDqLz!$ULSZ4&ENtOjz4*D+ z?oxNZ97fmYzVBF%;H!`plIUvA?~Y8#SZVEqMbdJKC%7P0&Y0q9$A%4GoceJN{eu+vm_|-YRzN`>0EjK`eq?2W`$rdHHF6@ z)^d1?ywR}Uk33>e9~Wjt6g=3Aw2$&6ii zUGV2VxhX{JGaUyTsv`t4uIvws7_v?X>I!cWCMz}}ugc)hWs_Kik^Ken0j=8e@=Emy zMAa5|k(OK{cmM52C1d;}5yg{cIn6uV3D5nT4(ZO1>zU3Qjmd@tm5e5UNKNN7Oiip! zQkKQKKP-+f)vWx`7Tw7Dv^A>mu@!$hR!K4gQ}^2p--!Klwx@I}lg%fa!COh?r}Ma_ z%7S$XhV`eG0!G#&U6h4tA4--SYdD!0S7zpiHc>A_n_;uR`?I$Bp9u8fYiv{i&H@8q zH+(*|ITNzHXrM|1ycW&Gw)W1d@8hP=E@v}eq(@_GSWZ~Ak0tEFjVt&iYOm^k;+1g_ zvm2G{qV}x+Jfa}qitcjvHP*@fMJ>d^oNZ8$$D7F8f8$)X%dA$wAQe3^sCk^4d6Os8 z%d9C-Q?#nMnPz{*(K!v(PACl2LMACoS07;VW@lmv#nxDCvmAr`UbpCg4zckaL}td# z?WP*^K3*wv6lT2*&sXaDqI5h{=KEnB9C(Ov#JpA@wTY#teFrIER6&8;wh7yQ%Hh`O zXg{914SDwdH0D>*6<$MJjeTIt!B;%rkY@`H0ZcLY+4AHgP3=26-m|Y8k`*`l9wRB5 z9e+Gd_C(6KlMIe@zW~Jqh1sMaH})l^gLkCH55{#UqvmHg|8z`Njl0aWB`35Fie;N^ zSdeHt9n6$vog7Q;W(Ukj+|4)(azq6c?;}v3AM9D!DIwmhY9|b)Hn}k{>04SGOzhl# zup#!0?C?dwg5NlCd)_MJZTX5#eMC{tn^g1T&!%F2XF0^%dn6D^HSQZCY7 zXO#p3AV>-^kDX2F5Y?~!_34s1c-|)ZYwzR;!s$85c<;44Tox9NYG<4M9n~tk0FzZj z)t)Q4l|@v1vqfKSxOPAmlrniQYNl5pBza%J<*#deNaQ6VqCoKxtq(W{LQlytn; zan&YxzX&<~p!^+DefnF8ykYj0cjXTm^oYBr+ukNO8z3% znOuWkZKHCV2@Q*Mfd0pxd1BS`o%t*orl!?|+|h^bpnLEX{2@`oh6#I3ls@y-bi b3+%{OIF;4p#*&Za;T}?A^59aDPhbBJfy^6O diff --git a/eBPF_Supermarket/Stack_Analyser/assets/image-20230528174207-3lf5d5j.png b/eBPF_Supermarket/Stack_Analyser/assets/image-20230528174207-3lf5d5j.png deleted file mode 100644 index 9e34ce53bbbc9a576ccd7a32d72a4202d0f6396b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73285 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

T_YpU5j({vecMxk;=|2MJe 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 diff --git a/eBPF_Supermarket/Stack_Analyser/assets/image-20230530164150-2f9ylpx.png b/eBPF_Supermarket/Stack_Analyser/assets/image-20230530164150-2f9ylpx.png deleted file mode 100644 index ad8ad91409e470c56698a29dac43dadf718d6788..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30567 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
vl8q8PN~y3hJLv6Qxp4I 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%0A;eU$FS;X47wmH%Pzxl&Nk&)HO9+%^?j_; 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 c_m39Ni9L#Q$`>=z|AK*Qv+XvU8m(^b diff --git a/eBPF_Supermarket/Stack_Analyser/assets/stack.svg b/eBPF_Supermarket/Stack_Analyser/assets/stack.svg deleted file mode 100644 index 7a10d3aa0..000000000 --- a/eBPF_Supermarket/Stack_Analyser/assets/stack.svg +++ /dev/null @@ -1,4757 +0,0 @@ - - - - - - - - - - - - - - -Flame Graph - -Reset Zoom -Search -ic - - - -update_rq_clock (1 samples, 0.03%) - - - -ttm_pool_alloc (2 samples, 0.05%) - - - -unix_destruct_scm (1 samples, 0.03%) - - - -__common_interrupt (1 samples, 0.03%) - - - -page_cache_ra_unbounded (6 samples, 0.15%) - - - -path_mount (2 samples, 0.05%) - - - -rcu_core_si (7 samples, 0.18%) - - - -vmw_execbuf_ioctl (8 samples, 0.20%) - - - -generic_writepages (2 samples, 0.05%) - - - -ksys_readahead (1 samples, 0.03%) - - - -down_read (1 samples, 0.03%) - - - -sysvec_call_function_single (2 samples, 0.05%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -wake_up_process (1 samples, 0.03%) - - - -__rq_qos_throttle (2 samples, 0.05%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -down_read (2 samples, 0.05%) - - - -blk_mq_run_hw_queue (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -run_rebalance_domains (4 samples, 0.10%) - - - -mptspi_qcmd (1 samples, 0.03%) - - - -__sysvec_call_function_single (2 samples, 0.05%) - - - -pick_next_task_fair (1 samples, 0.03%) - - - -wake_up_process (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -schedule_hrtimeout_range_clock (160 samples, 4.01%) -sche.. - - -sget_fc (1 samples, 0.03%) - - - -__sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -unix_stream_recvmsg (1 samples, 0.03%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -__wake_up_common_lock (1 samples, 0.03%) - - - -__queue_work (1 samples, 0.03%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -tick_sched_timer (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -cpu_startup_entry (9 samples, 0.23%) - - - -update_rq_clock (1 samples, 0.03%) - - - -irqentry_exit_to_user_mode (9 samples, 0.23%) - - - -n_tty_poll (17 samples, 0.43%) - - - -kernfs_fop_open (1 samples, 0.03%) - - - -blk_finish_plug (1 samples, 0.03%) - - - -lzma2_lzma (1 samples, 0.03%) - - - -schedule (1 samples, 0.03%) - - - -__irq_wake_thread (1 samples, 0.03%) - - - -vmmouse_process_byte (1 samples, 0.03%) - - - -lookup_fast (1 samples, 0.03%) - - - -wait_for_completion_io_timeout (3 samples, 0.08%) - - - -update_rq_clock (1 samples, 0.03%) - - - -__cond_resched (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (17 samples, 0.43%) - - - -__blk_mq_delay_run_hw_queue (1 samples, 0.03%) - - - -__rseq_handle_notify_resume (1 samples, 0.03%) - - - -schedule (8 samples, 0.20%) - - - -wake_up_process (1 samples, 0.03%) - - - -__wake_up_common (1 samples, 0.03%) - - - -wake_up_process (15 samples, 0.38%) - - - -__sysvec_call_function_single (1 samples, 0.03%) - - - -__cond_resched (61 samples, 1.53%) - - - -__cond_resched (3 samples, 0.08%) - - - -__schedule (18 samples, 0.45%) - - - -__d_alloc (1 samples, 0.03%) - - - -flush_smp_call_function_queue (1 samples, 0.03%) - - - -vmw_ttm_populate (2 samples, 0.05%) - - - -__wake_up (27 samples, 0.68%) - - - -schedule (523 samples, 13.10%) -schedule - - -squashfs_readpage_block (3 samples, 0.08%) - - - -update_rq_clock (7 samples, 0.18%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -vmmouse_process_byte (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -vmw_user_fence_create (1 samples, 0.03%) - - - -wake_up_q (1 samples, 0.03%) - - - -__alloc_pages (1 samples, 0.03%) - - - -irq_exit_rcu (1 samples, 0.03%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -do_compat_epoll_pwait.part.0 (1 samples, 0.03%) - - - -__sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -hrtimer_interrupt (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (2 samples, 0.05%) - - - -squashfs_bio_read (7 samples, 0.18%) - - - -delayed_work_timer_fn (15 samples, 0.38%) - - - -schedule (118 samples, 2.96%) -sc.. - - -irqentry_exit (119 samples, 2.98%) -ir.. - - -update_process_times (1 samples, 0.03%) - - - -update_rq_clock (61 samples, 1.53%) - - - -do_iter_read (4 samples, 0.10%) - - - -pagecache_get_page (1 samples, 0.03%) - - - -tick_sched_handle (1 samples, 0.03%) - - - -vmballoon_send_start (1 samples, 0.03%) - - - -__hrtimer_run_queues (2 samples, 0.05%) - - - -sysvec_call_function_single (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -sysvec_apic_timer_interrupt (17 samples, 0.43%) - - - -finish_task_switch.isra.0 (2 samples, 0.05%) - - - -exit_signals (3 samples, 0.08%) - - - -filemap_get_pages (2 samples, 0.05%) - - - -irq_exit_rcu (1 samples, 0.03%) - - - -dec_block (1 samples, 0.03%) - - - -run_rebalance_domains (1 samples, 0.03%) - - - -exit_to_user_mode_prepare (599 samples, 15.00%) -exit_to_user_mode_prepare - - -loop_process_work (8 samples, 0.20%) - - - -update_rq_clock (2 samples, 0.05%) - - - -schedule_timeout (3 samples, 0.08%) - - - -__fget_files (1 samples, 0.03%) - - - -schedule (8 samples, 0.20%) - - - -__sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -vmw_execbuf_process (6 samples, 0.15%) - - - -flush_smp_call_function_queue (2 samples, 0.05%) - - - -pick_next_task_fair (4 samples, 0.10%) - - - -path_put (1 samples, 0.03%) - - - -vmw_generic_ioctl (8 samples, 0.20%) - - - -update_rq_clock (156 samples, 3.91%) -upda.. - - -__common_interrupt (1 samples, 0.03%) - - - -queue_work_on (1 samples, 0.03%) - - - -__hrtimer_run_queues (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -unmap_vmas (1 samples, 0.03%) - - - -blk_mq_dispatch_rq_list (1 samples, 0.03%) - - - -update_rq_clock (118 samples, 2.96%) -up.. - - -__softirqentry_text_start (3 samples, 0.08%) - - - -flush_smp_call_function_queue (17 samples, 0.43%) - - - -update_process_times (1 samples, 0.03%) - - - -alloc_pages (3 samples, 0.08%) - - - -wake_up_process (1 samples, 0.03%) - - - -update_rq_clock (3 samples, 0.08%) - - - -update_rq_clock (1 samples, 0.03%) - - - -do_group_exit (4 samples, 0.10%) - - - -hrtimer_nanosleep (1 samples, 0.03%) - - - -hrtimer_wakeup (15 samples, 0.38%) - - - -vmw_execbuf_fence_commands (3 samples, 0.08%) - - - -vmballoon_work (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -update_rq_clock (11 samples, 0.28%) - - - -asm_sysvec_call_function_single (1 samples, 0.03%) - - - -update_rq_clock (11 samples, 0.28%) - - - -filemap_fault (17 samples, 0.43%) - - - -cpuidle_enter (6 samples, 0.15%) - - - -__sysvec_call_function_single (24 samples, 0.60%) - - - -__common_interrupt (1 samples, 0.03%) - - - -wake_up_process (2 samples, 0.05%) - - - -__sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -update_process_times (1 samples, 0.03%) - - - -do_dentry_open (1 samples, 0.03%) - - - -__sched_text_start (3 samples, 0.08%) - - - -tick_sched_timer (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -newidle_balance (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -finish_task_switch.isra.0 (1 samples, 0.03%) - - - -flush_smp_call_function_queue (2 samples, 0.05%) - - - -drm_atomic_helper_commit_planes (1 samples, 0.03%) - - - -unmap_single_vma (1 samples, 0.03%) - - - -kernel_clone (2 samples, 0.05%) - - - -__fsnotify_parent (46 samples, 1.15%) - - - -vmw_resource_unpin (61 samples, 1.53%) - - - -__wake_up (1 samples, 0.03%) - - - -vmw_fences_update (8 samples, 0.20%) - - - -blk_mq_sched_insert_requests (1 samples, 0.03%) - - - -wake_up_process (1 samples, 0.03%) - - - -__softirqentry_text_start (58 samples, 1.45%) - - - -__alloc_pages (2 samples, 0.05%) - - - -finish_task_switch.isra.0 (1 samples, 0.03%) - - - -vmmouse_report_events (1 samples, 0.03%) - - - -generic_file_read_iter (2 samples, 0.05%) - - - -__vmw_fences_update (8 samples, 0.20%) - - - -__queue_work (2 samples, 0.05%) - - - -update_rq_clock (12 samples, 0.30%) - - - -sysvec_apic_timer_interrupt (7 samples, 0.18%) - - - -hrtimer_interrupt (1 samples, 0.03%) - - - -x86_64_start_kernel (9 samples, 0.23%) - - - -wb_do_writeback (2 samples, 0.05%) - - - -__x64_sys_ioctl (8 samples, 0.20%) - - - -eventfd_write (131 samples, 3.28%) -eve.. - - -delayed_work_timer_fn (1 samples, 0.03%) - - - -autoremove_wake_function (1 samples, 0.03%) - - - -insert_work (1 samples, 0.03%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -__submit_bio (2 samples, 0.05%) - - - -__cond_resched (2 samples, 0.05%) - - - -__wake_up_common (26 samples, 0.65%) - - - -update_rq_clock (3 samples, 0.08%) - - - -irq_exit_rcu (1 samples, 0.03%) - - - -schedule_timeout (7 samples, 0.18%) - - - -kblockd_mod_delayed_work_on (1 samples, 0.03%) - - - -do_sys_openat2 (4 samples, 0.10%) - - - -__schedule (3 samples, 0.08%) - - - -thread_group_cputime (156 samples, 3.91%) -thre.. - - -blk_done_softirq (3 samples, 0.08%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -wait_on_page_bit_common (4 samples, 0.10%) - - - -update_rq_clock (2 samples, 0.05%) - - - -schedule (4 samples, 0.10%) - - - -rebalance_domains (7 samples, 0.18%) - - - -submit_bio (1 samples, 0.03%) - - - -__sysvec_call_function_single (2 samples, 0.05%) - - - -force_page_cache_ra (1 samples, 0.03%) - - - -run_timer_softirq (1 samples, 0.03%) - - - -schedule (160 samples, 4.01%) -sche.. - - -input_to_handler (1 samples, 0.03%) - - - -dec_main (1 samples, 0.03%) - - - -hrtimer_interrupt (1 samples, 0.03%) - - - -arch_call_rest_init (9 samples, 0.23%) - - - -update_rq_clock (1 samples, 0.03%) - - - -__mutex_unlock_slowpath.constprop.0 (1 samples, 0.03%) - - - -on_each_cpu_cond_mask (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -scsi_complete (1 samples, 0.03%) - - - -irq_exit_rcu (1 samples, 0.03%) - - - -do_exit (4 samples, 0.10%) - - - -do_epoll_wait (1 samples, 0.03%) - - - -squashfs_readpage_block (8 samples, 0.20%) - - - -__sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -do_task_dead (38 samples, 0.95%) - - - -sock_recvmsg (1 samples, 0.03%) - - - -__queue_work (1 samples, 0.03%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -__schedule (5 samples, 0.13%) - - - -asm_common_interrupt (1 samples, 0.03%) - - - -cpuidle_enter_state (6 samples, 0.15%) - - - -hrtimer_wakeup (1 samples, 0.03%) - - - -__fget_light (1 samples, 0.03%) - - - -call_timer_fn (1 samples, 0.03%) - - - -tick_sched_handle (1 samples, 0.03%) - - - -sysvec_call_function_single (1 samples, 0.03%) - - - -flush_tlb_mm_range (1 samples, 0.03%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -insert_work (1 samples, 0.03%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -sysvec_call_function_single (1 samples, 0.03%) - - - -wb_workfn (2 samples, 0.05%) - - - -asm_sysvec_apic_timer_interrupt (2 samples, 0.05%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -irq_exit_rcu (1 samples, 0.03%) - - - -__cond_resched (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -tick_sched_timer (12 samples, 0.30%) - - - -irq_exit_rcu (7 samples, 0.18%) - - - -sock_wfree (1 samples, 0.03%) - - - -__hrtimer_run_queues (1 samples, 0.03%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -x86_64_start_reservations (9 samples, 0.23%) - - - -do_sys_poll (161 samples, 4.03%) -do_s.. - - -insert_work (1 samples, 0.03%) - - - -schedule (51 samples, 1.28%) - - - -insert_work (2 samples, 0.05%) - - - -tick_sched_handle (1 samples, 0.03%) - - - -vmw_unlocked_ioctl (8 samples, 0.20%) - - - -do_timerfd_settime (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -vfs_iter_read (4 samples, 0.10%) - - - -schedule (3 samples, 0.08%) - - - -do_filp_open (4 samples, 0.10%) - - - -ttm_tt_populate (2 samples, 0.05%) - - - -vfs_open (1 samples, 0.03%) - - - -__blk_mq_sched_dispatch_requests (1 samples, 0.03%) - - - -__softirqentry_text_start (6 samples, 0.15%) - - - -wake_up_q (144 samples, 3.61%) -wake.. - - -__cond_resched (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -__cond_resched (1 samples, 0.03%) - - - -__schedule (1 samples, 0.03%) - - - -newidle_balance (4 samples, 0.10%) - - - -evdev_pass_values.part.0 (1 samples, 0.03%) - - - -vmw_cmd_send_fence (2 samples, 0.05%) - - - -update_rq_clock (3 samples, 0.08%) - - - -alloc_pages (1 samples, 0.03%) - - - -__x64_sys_write (178 samples, 4.46%) -__x64.. - - -vmw_du_crtc_destroy_state (1 samples, 0.03%) - - - -__local_bh_enable_ip (1 samples, 0.03%) - - - -update_rq_clock (197 samples, 4.93%) -update.. - - -__cond_resched (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -psmouse_handle_byte (1 samples, 0.03%) - - - -irq_exit_rcu (1 samples, 0.03%) - - - -__blk_mq_delay_run_hw_queue (1 samples, 0.03%) - - - -__sysvec_call_function_single (154 samples, 3.86%) -__sy.. - - -update_rq_clock (7 samples, 0.18%) - - - -__alloc_pages (3 samples, 0.08%) - - - -__blk_mq_run_hw_queue (1 samples, 0.03%) - - - -schedule (3 samples, 0.08%) - - - -remove_vma (1 samples, 0.03%) - - - -tty_ldisc_ref_wait (1 samples, 0.03%) - - - -do_fault (17 samples, 0.43%) - - - -update_rq_clock (1 samples, 0.03%) - - - -update_rq_clock (4 samples, 0.10%) - - - -run_timer_softirq (1 samples, 0.03%) - - - -exit_mmap (1 samples, 0.03%) - - - -drm_atomic_state_default_clear (1 samples, 0.03%) - - - -__queue_work (7 samples, 0.18%) - - - -do_softirq (1 samples, 0.03%) - - - -__hrtimer_run_queues (2 samples, 0.05%) - - - -run_rebalance_domains (1 samples, 0.03%) - - - -handle_irq_event (1 samples, 0.03%) - - - -pollwake (26 samples, 0.65%) - - - -rcu_core (7 samples, 0.18%) - - - -kjournald2 (4 samples, 0.10%) - - - -__sysvec_apic_timer_interrupt (2 samples, 0.05%) - - - -do_nanosleep (4 samples, 0.10%) - - - -start_kernel (9 samples, 0.23%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -__cond_resched (2 samples, 0.05%) - - - -call_timer_fn (2 samples, 0.05%) - - - -open_last_lookups (2 samples, 0.05%) - - - -tick_sched_timer (1 samples, 0.03%) - - - -__page_cache_alloc (3 samples, 0.08%) - - - -__run_timers.part.0 (2 samples, 0.05%) - - - -rcu_core (1 samples, 0.03%) - - - -tty_poll (19 samples, 0.48%) - - - -psmouse_interrupt (1 samples, 0.03%) - - - -flush_smp_call_function_queue (154 samples, 3.86%) -flus.. - - -schedule (2 samples, 0.05%) - - - -wake_up_process (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -do_poll.constprop.0 (53 samples, 1.33%) - - - -update_rq_clock (4 samples, 0.10%) - - - -__softirqentry_text_start (2 samples, 0.05%) - - - -__schedule (1 samples, 0.03%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (7 samples, 0.18%) - - - -dma_fence_signal_locked (7 samples, 0.18%) - - - -scsi_finish_command (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -ext4_readahead (1 samples, 0.03%) - - - -asm_exc_page_fault (29 samples, 0.73%) - - - -raise_softirq (2 samples, 0.05%) - - - -__x64_sys_clone (2 samples, 0.05%) - - - -irq_exit_rcu (1 samples, 0.03%) - - - -irq_exit_rcu (1 samples, 0.03%) - - - -queue_work_on (1 samples, 0.03%) - - - -xz_dec_lzma2_run (1 samples, 0.03%) - - - -hrtimer_interrupt (2 samples, 0.05%) - - - -__sysvec_call_function_single (1 samples, 0.03%) - - - -handle_pte_fault (18 samples, 0.45%) - - - -asm_sysvec_call_function_single (17 samples, 0.43%) - - - -insert_work (1 samples, 0.03%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -handle_fasteoi_irq (1 samples, 0.03%) - - - -__percpu_init_rwsem (1 samples, 0.03%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -__wake_up_common (1 samples, 0.03%) - - - -tick_sched_handle (1 samples, 0.03%) - - - -__wake_up (1 samples, 0.03%) - - - -__wake_up_common (1 samples, 0.03%) - - - -wake_up_process (1 samples, 0.03%) - - - -asm_common_interrupt (1 samples, 0.03%) - - - -irqentry_exit (8 samples, 0.20%) - - - -__hrtimer_run_queues (14 samples, 0.35%) - - - -squashfs_readpage (8 samples, 0.20%) - - - -__wake_up_locked_key (130 samples, 3.26%) -__w.. - - -__x64_sys_ppoll (53 samples, 1.33%) - - - -loop_rootcg_workfn (8 samples, 0.20%) - - - -__sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -update_rq_clock (2 samples, 0.05%) - - - -hrtimer_wakeup (1 samples, 0.03%) - - - -new_slab (1 samples, 0.03%) - - - -wbt_wait (2 samples, 0.05%) - - - -filemap_read (2 samples, 0.05%) - - - -sched_autogroup_exit_task (37 samples, 0.93%) - - - -get_tree_nodev (1 samples, 0.03%) - - - -pick_next_task_fair (1 samples, 0.03%) - - - -do_idle (6 samples, 0.15%) - - - -__irq_wake_thread (1 samples, 0.03%) - - - -tty_write (1 samples, 0.03%) - - - -do_epoll_wait (3 samples, 0.08%) - - - -handle_mm_fault (18 samples, 0.45%) - - - -ttm_bo_validate (2 samples, 0.05%) - - - -__common_interrupt (1 samples, 0.03%) - - - -schedule (335 samples, 8.39%) -schedule - - -common_interrupt (9 samples, 0.23%) - - - -exit_to_user_mode_prepare (9 samples, 0.23%) - - - -update_rq_clock (26 samples, 0.65%) - - - -update_rq_clock (2 samples, 0.05%) - - - -pty_write (1 samples, 0.03%) - - - -__sysvec_apic_timer_interrupt (14 samples, 0.35%) - - - -vmw_du_plane_cleanup_fb (61 samples, 1.53%) - - - -__handle_irq_event_percpu (1 samples, 0.03%) - - - -__kmalloc (1 samples, 0.03%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -hrtimer_interrupt (14 samples, 0.35%) - - - -default_wake_function (1 samples, 0.03%) - - - -vm_mmap_pgoff (1 samples, 0.03%) - - - -___slab_alloc (1 samples, 0.03%) - - - -unix_stream_read_generic (1 samples, 0.03%) - - - -sysvec_call_function_single (2 samples, 0.05%) - - - -do_user_addr_fault (21 samples, 0.53%) - - - -flush_smp_call_function_queue (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -__wake_up (1 samples, 0.03%) - - - -kfree (1 samples, 0.03%) - - - -input_handle_event (1 samples, 0.03%) - - - -__do_sys_clone (2 samples, 0.05%) - - - -acpi_idle_enter (7 samples, 0.18%) - - - -schedule (809 samples, 20.26%) -schedule - - -pick_next_task (14 samples, 0.35%) - - - -tick_sched_handle (12 samples, 0.30%) - - - -update_rq_clock (2 samples, 0.05%) - - - -do_iter_readv_writev (4 samples, 0.10%) - - - -blk_flush_plug_list (1 samples, 0.03%) - - - -smpboot_thread_fn (58 samples, 1.45%) - - - -update_rq_clock (7 samples, 0.18%) - - - -update_rq_clock (16 samples, 0.40%) - - - -kthread (1,324 samples, 33.16%) -kthread - - -irq_exit_rcu (2 samples, 0.05%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -__cond_resched (16 samples, 0.40%) - - - -drm_ioctl_kernel (8 samples, 0.20%) - - - -hrtimer_interrupt (1 samples, 0.03%) - - - -pick_next_task (4 samples, 0.10%) - - - -__cond_resched (2 samples, 0.05%) - - - -submit_bio_wait (7 samples, 0.18%) - - - -__alloc_pages (3 samples, 0.08%) - - - -update_process_times (1 samples, 0.03%) - - - -irq_exit_rcu (1 samples, 0.03%) - - - -wake_up_process (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -asm_common_interrupt (9 samples, 0.23%) - - - -flush_smp_call_function_queue (1 samples, 0.03%) - - - -drm_ioctl (8 samples, 0.20%) - - - -__wake_up (1 samples, 0.03%) - - - -pick_next_task (1 samples, 0.03%) - - - -clear_page_orig (2 samples, 0.05%) - - - -secondary_startup_64_no_verify (15 samples, 0.38%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -run_timer_softirq (16 samples, 0.40%) - - - -update_rq_clock (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -__hrtimer_run_queues (1 samples, 0.03%) - - - -squashfs_readpage_block (2 samples, 0.05%) - - - -page_cache_ra_unbounded (11 samples, 0.28%) - - - -tty_ldisc_receive_buf (27 samples, 0.68%) - - - -update_rq_clock (24 samples, 0.60%) - - - -update_rq_clock (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -do_syslog.part.0 (2 samples, 0.05%) - - - -hrtimer_interrupt (2 samples, 0.05%) - - - -tick_sched_handle (1 samples, 0.03%) - - - -update_rq_clock (37 samples, 0.93%) - - - -squashfs_read_data (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -do_futex (547 samples, 13.70%) -do_futex - - -update_process_times (2 samples, 0.05%) - - - -__sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -hrtimer_interrupt (15 samples, 0.38%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -vmw_validation_bo_validate_single (2 samples, 0.05%) - - - -blk_update_request (2 samples, 0.05%) - - - -squashfs_readpage (3 samples, 0.08%) - - - -ext4_mpage_readpages (1 samples, 0.03%) - - - -zap_pmd_range.isra.0 (1 samples, 0.03%) - - - -update_rq_clock (4 samples, 0.10%) - - - -__x64_sys_exit_group (4 samples, 0.10%) - - - -schedule (2 samples, 0.05%) - - - -vfs_get_tree (1 samples, 0.03%) - - - -input_event (1 samples, 0.03%) - - - -vmwgfx_wait_cb (7 samples, 0.18%) - - - -irqentry_exit_to_user_mode (353 samples, 8.84%) -irqentry_exi.. - - -__softirqentry_text_start (1 samples, 0.03%) - - - -syscall_exit_to_user_mode (599 samples, 15.00%) -syscall_exit_to_user_mode - - -schedule_hrtimeout_range_clock (3 samples, 0.08%) - - - -__cond_resched (1 samples, 0.03%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -generic_smp_call_function_single_interrupt (1 samples, 0.03%) - - - -asm_sysvec_call_function_single (2 samples, 0.05%) - - - -do_poll.constprop.0 (161 samples, 4.03%) -do_p.. - - -squashfs_get_datablock (3 samples, 0.08%) - - - -run_rebalance_domains (1 samples, 0.03%) - - - -schedule (7 samples, 0.18%) - - - -vmw_event_fence_action_queue (1 samples, 0.03%) - - - -__wake_up_common_lock (27 samples, 0.68%) - - - -lzma_literal (1 samples, 0.03%) - - - -irq_exit_rcu (58 samples, 1.45%) - - - -kmsg_read (2 samples, 0.05%) - - - -ondemand_readahead (6 samples, 0.15%) - - - -blk_mq_submit_bio (2 samples, 0.05%) - - - -update_rq_clock (142 samples, 3.56%) -upd.. - - -__handle_irq_event_percpu (1 samples, 0.03%) - - - -default_wake_function (26 samples, 0.65%) - - - -asm_sysvec_call_function_single (2 samples, 0.05%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -alloc_pages (2 samples, 0.05%) - - - -asm_sysvec_call_function_single (2 samples, 0.05%) - - - -__drm_atomic_state_free (1 samples, 0.03%) - - - -__sysvec_apic_timer_interrupt (2 samples, 0.05%) - - - -ext4_file_read_iter (4 samples, 0.10%) - - - -update_rq_clock (8 samples, 0.20%) - - - -common_interrupt (1 samples, 0.03%) - - - -pick_next_task (1 samples, 0.03%) - - - -write_cache_pages (2 samples, 0.05%) - - - -__cond_resched (1 samples, 0.03%) - - - -generic_smp_call_function_single_interrupt (24 samples, 0.60%) - - - -__submit_bio (1 samples, 0.03%) - - - -do_tty_write (1 samples, 0.03%) - - - -hrtimer_interrupt (1 samples, 0.03%) - - - -blk_mq_sched_dispatch_requests (1 samples, 0.03%) - - - -kernfs_dop_revalidate (1 samples, 0.03%) - - - -__cond_resched (46 samples, 1.15%) - - - -update_rq_clock (1 samples, 0.03%) - - - -scsi_dispatch_cmd (1 samples, 0.03%) - - - -submit_bio_checks (1 samples, 0.03%) - - - -mutex_lock_killable (1 samples, 0.03%) - - - -wake_up_process (7 samples, 0.18%) - - - -blk_mq_flush_plug_list (1 samples, 0.03%) - - - -zap_pte_range (1 samples, 0.03%) - - - -insert_work (7 samples, 0.18%) - - - -generic_file_read_iter (4 samples, 0.10%) - - - -generic_smp_call_function_single_interrupt (2 samples, 0.05%) - - - -flush_smp_call_function_queue (2 samples, 0.05%) - - - -n_tty_write (1 samples, 0.03%) - - - -cgroup_post_fork (2 samples, 0.05%) - - - -update_rq_clock (130 samples, 3.26%) -upd.. - - -irq_exit_rcu (1 samples, 0.03%) - - - -flush_smp_call_function_queue (1 samples, 0.03%) - - - -wake_up_process (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -finish_task_switch.isra.0 (1 samples, 0.03%) - - - -schedule_idle (2 samples, 0.05%) - - - -__wake_up_common (1 samples, 0.03%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -syslog_print (2 samples, 0.05%) - - - -filemap_update_page (4 samples, 0.10%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -inode_permission (1 samples, 0.03%) - - - -unmap_region (1 samples, 0.03%) - - - -asm_sysvec_call_function_single (1 samples, 0.03%) - - - -ep_poll (3 samples, 0.08%) - - - -hrtimer_wakeup (1 samples, 0.03%) - - - -__cond_resched (3 samples, 0.08%) - - - -submit_bio (2 samples, 0.05%) - - - -drm_atomic_helper_commit_tail (62 samples, 1.55%) - - - -lo_complete_rq (2 samples, 0.05%) - - - -try_to_wake_up (1 samples, 0.03%) - - - -pollwake (130 samples, 3.26%) -pol.. - - -schedule_hrtimeout_range (3 samples, 0.08%) - - - -start_secondary (6 samples, 0.15%) - - - -__queue_delayed_work (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -ep_poll (1 samples, 0.03%) - - - -__wake_up_common (1 samples, 0.03%) - - - -run_rebalance_domains (33 samples, 0.83%) - - - -do_sched_yield (182 samples, 4.56%) -do_sc.. - - -irq_exit_rcu (1 samples, 0.03%) - - - -io_schedule (2 samples, 0.05%) - - - -sysvec_apic_timer_interrupt (3 samples, 0.08%) - - - -default_wake_function (130 samples, 3.26%) -def.. - - -wake_up_process (2 samples, 0.05%) - - - -update_process_times (12 samples, 0.30%) - - - -dput (1 samples, 0.03%) - - - -queue_work_on (2 samples, 0.05%) - - - -__x64_sys_nanosleep (1 samples, 0.03%) - - - -squashfs_get_datablock (1 samples, 0.03%) - - - -__handle_mm_fault (18 samples, 0.45%) - - - -wake_up_process (11 samples, 0.28%) - - - -wake_up_process (1 samples, 0.03%) - - - -n_tty_receive_buf_common (27 samples, 0.68%) - - - -blk_mq_run_work_fn (1 samples, 0.03%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -schedule (403 samples, 10.09%) -schedule - - -__schedule (1 samples, 0.03%) - - - -mutex_lock (2 samples, 0.05%) - - - -asm_sysvec_apic_timer_interrupt (4 samples, 0.10%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -memcg_slab_free_hook (1 samples, 0.03%) - - - -allocate_slab (1 samples, 0.03%) - - - -run_rebalance_domains (1 samples, 0.03%) - - - -__wake_up_common_lock (1 samples, 0.03%) - - - -__cond_resched (1 samples, 0.03%) - - - -link_path_walk.part.0.constprop.0 (1 samples, 0.03%) - - - -flush_smp_call_function_queue (1 samples, 0.03%) - - - -__blk_mq_run_hw_queue (1 samples, 0.03%) - - - -__wake_up (1 samples, 0.03%) - - - -hrtimer_interrupt (1 samples, 0.03%) - - - -squashfs_cache_get (3 samples, 0.08%) - - - -rebalance_domains (4 samples, 0.10%) - - - -call_timer_fn (15 samples, 0.38%) - - - -__softirqentry_text_start (7 samples, 0.18%) - - - -__x64_sys_clock_nanosleep (4 samples, 0.10%) - - - -blk_mq_end_request (2 samples, 0.05%) - - - -__wait_for_common (7 samples, 0.18%) - - - -irq_exit_rcu (1 samples, 0.03%) - - - -__flush_work.isra.0 (17 samples, 0.43%) - - - -unix_write_space (1 samples, 0.03%) - - - -update_rq_clock (335 samples, 8.39%) -update_rq_c.. - - -wait_for_completion_io_timeout (7 samples, 0.18%) - - - -__run_timers.part.0 (1 samples, 0.03%) - - - -pollwake (1 samples, 0.03%) - - - -__cond_resched (1 samples, 0.03%) - - - -vmw_update_seqno (2 samples, 0.05%) - - - -cpuidle_enter (7 samples, 0.18%) - - - -squashfs_read_data (3 samples, 0.08%) - - - -hrtimer_nanosleep (4 samples, 0.10%) - - - -exit_to_user_mode_loop (119 samples, 2.98%) -ex.. - - -scsi_io_completion (1 samples, 0.03%) - - - -__sysvec_call_function_single (1 samples, 0.03%) - - - -filemap_read (4 samples, 0.10%) - - - -schedule (20 samples, 0.50%) - - - -asm_sysvec_call_function_single (1 samples, 0.03%) - - - -schedule_hrtimeout_range (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -handle_irq_event (1 samples, 0.03%) - - - -do_req_filebacked (4 samples, 0.10%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -update_rq_clock (2 samples, 0.05%) - - - -__hrtimer_run_queues (1 samples, 0.03%) - - - -__do_munmap (1 samples, 0.03%) - - - -blkdev_writepages (2 samples, 0.05%) - - - -update_rq_clock (1 samples, 0.03%) - - - -asm_sysvec_call_function_single (1 samples, 0.03%) - - - -tick_sched_timer (1 samples, 0.03%) - - - -smp_call_function_many_cond (1 samples, 0.03%) - - - -i8042_interrupt (1 samples, 0.03%) - - - -wake_up_process (1 samples, 0.03%) - - - -update_rq_clock (34 samples, 0.85%) - - - -schedule_hrtimeout_range (160 samples, 4.01%) -sche.. - - -tty_flip_buffer_push (1 samples, 0.03%) - - - -__sysvec_call_function_single (17 samples, 0.43%) - - - -blk_mq_do_dispatch_sched (1 samples, 0.03%) - - - -update_rq_clock (17 samples, 0.43%) - - - -new_sync_write (1 samples, 0.03%) - - - -sysvec_call_function_single (24 samples, 0.60%) - - - -vmw_generic_waiter_add (1 samples, 0.03%) - - - -rebalance_domains (11 samples, 0.28%) - - - -exc_page_fault (29 samples, 0.73%) - - - -xz_dec_run (1 samples, 0.03%) - - - -__x64_sys_sched_yield (182 samples, 4.56%) -__x64.. - - -update_rq_clock (2 samples, 0.05%) - - - -asm_common_interrupt (1 samples, 0.03%) - - - -schedule (34 samples, 0.85%) - - - -generic_smp_call_function_single_interrupt (17 samples, 0.43%) - - - -__x64_sys_openat (4 samples, 0.10%) - - - -submit_bio_noacct (1 samples, 0.03%) - - - -irq_exit_rcu (3 samples, 0.08%) - - - -call_timer_fn (1 samples, 0.03%) - - - -tty_buffer_flush_work (17 samples, 0.43%) - - - -update_rq_clock (1 samples, 0.03%) - - - -ksys_write (178 samples, 4.46%) -ksys_.. - - -__cond_resched (2 samples, 0.05%) - - - -mmput (1 samples, 0.03%) - - - -__wake_up_common_lock (1 samples, 0.03%) - - - -vfs_write (178 samples, 4.46%) -vfs_w.. - - -run_rebalance_domains (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -sysvec_call_function_single (2 samples, 0.05%) - - - -delayed_work_timer_fn (2 samples, 0.05%) - - - -update_rq_clock (1 samples, 0.03%) - - - -rebalance_domains (2 samples, 0.05%) - - - -handle_irq_event (1 samples, 0.03%) - - - -tick_sched_timer (1 samples, 0.03%) - - - -exit_to_user_mode_loop (9 samples, 0.23%) - - - -worker_thread (965 samples, 24.17%) -worker_thread - - -__hrtimer_run_queues (1 samples, 0.03%) - - - -ep_poll_callback (1 samples, 0.03%) - - - -__sysvec_call_function_single (2 samples, 0.05%) - - - -run_rebalance_domains (1 samples, 0.03%) - - - -read_pages (3 samples, 0.08%) - - - -update_rq_clock (1 samples, 0.03%) - - - -__x64_sys_mount (2 samples, 0.05%) - - - -cpuidle_idle_call (6 samples, 0.15%) - - - -ep_poll_callback (1 samples, 0.03%) - - - -process_timeout (1 samples, 0.03%) - - - -futex_wait (403 samples, 10.09%) -futex_wait - - -scsi_queue_rq (1 samples, 0.03%) - - - -irq_exit_rcu (1 samples, 0.03%) - - - -mptscsih_qcmd (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (192 samples, 4.81%) -asm_sy.. - - -sysvec_apic_timer_interrupt (192 samples, 4.81%) -sysvec.. - - -__x64_sys_epoll_pwait (1 samples, 0.03%) - - - -__x64_sys_read (9 samples, 0.23%) - - - -d_alloc_parallel (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -__wake_up_common_lock (1 samples, 0.03%) - - - -thread_group_cputime_adjusted (156 samples, 3.91%) -thre.. - - -unmap_page_range (1 samples, 0.03%) - - - -update_rq_clock (154 samples, 3.86%) -upda.. - - -__wake_up_common (130 samples, 3.26%) -__w.. - - -__fget_light (1 samples, 0.03%) - - - -run_timer_softirq (1 samples, 0.03%) - - - -update_rq_clock (144 samples, 3.61%) -upda.. - - -get_signal (75 samples, 1.88%) -g.. - - -tty_read (3 samples, 0.08%) - - - -generic_smp_call_function_single_interrupt (2 samples, 0.05%) - - - -__run_timers.part.0 (1 samples, 0.03%) - - - -i8042_interrupt (1 samples, 0.03%) - - - -vmw_validation_bo_validate (2 samples, 0.05%) - - - -skb_release_head_state (1 samples, 0.03%) - - - -asm_sysvec_call_function_single (24 samples, 0.60%) - - - -hrtimer_wakeup (2 samples, 0.05%) - - - -wake_up_process (1 samples, 0.03%) - - - -__blk_mq_sched_dispatch_requests (1 samples, 0.03%) - - - -submit_bio_wait (3 samples, 0.08%) - - - -update_rq_clock (1 samples, 0.03%) - - - -proc_reg_read (2 samples, 0.05%) - - - -do_sys_times (156 samples, 3.91%) -do_s.. - - -evdev_pass_values.part.0 (1 samples, 0.03%) - - - -update_rq_clock (51 samples, 1.28%) - - - -pollwake (1 samples, 0.03%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -delayed_work_timer_fn (1 samples, 0.03%) - - - -mod_delayed_work_on (1 samples, 0.03%) - - - -ret_from_fork (1,324 samples, 33.16%) -ret_from_fork - - -vmmouse_report_events (1 samples, 0.03%) - - - -sysvec_call_function_single (1 samples, 0.03%) - - - -do_page_cache_ra (11 samples, 0.28%) - - - -update_rq_clock (37 samples, 0.93%) - - - -run_ksoftirqd (7 samples, 0.18%) - - - -submit_bio_noacct (2 samples, 0.05%) - - - -call_timer_fn (1 samples, 0.03%) - - - -mpt_put_msg_frame (1 samples, 0.03%) - - - -rcu_work_rcufn (7 samples, 0.18%) - - - -__queue_work (1 samples, 0.03%) - - - -update_rq_clock (2 samples, 0.05%) - - - -sysvec_apic_timer_interrupt (4 samples, 0.10%) - - - -update_rq_clock (1 samples, 0.03%) - - - -rcu_gp_fqs_loop (72 samples, 1.80%) -r.. - - -update_rq_clock (523 samples, 13.10%) -update_rq_clock - - -complete (2 samples, 0.05%) - - - -_raw_spin_unlock_irqrestore (1 samples, 0.03%) - - - -handle_irq_event (1 samples, 0.03%) - - - -sock_read_iter (1 samples, 0.03%) - - - -do_syslog (2 samples, 0.05%) - - - -__x64_sys_times (156 samples, 3.91%) -__x6.. - - -update_rq_clock (2 samples, 0.05%) - - - -hrtimer_interrupt (1 samples, 0.03%) - - - -irq_exit_rcu (1 samples, 0.03%) - - - -__sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -__softirqentry_text_start (4 samples, 0.10%) - - - -__x64_sys_epoll_wait (3 samples, 0.08%) - - - -update_rq_clock (1 samples, 0.03%) - - - -path_openat (4 samples, 0.10%) - - - -serio_interrupt (1 samples, 0.03%) - - - -exit_to_user_mode_loop (599 samples, 15.00%) -exit_to_user_mode_loop - - -do_idle (9 samples, 0.23%) - - - -dput (46 samples, 1.15%) - - - -finish_task_switch.isra.0 (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -consume_skb (1 samples, 0.03%) - - - -generic_smp_call_function_single_interrupt (1 samples, 0.03%) - - - -asm_sysvec_call_function_single (507 samples, 12.70%) -asm_sysvec_call_fun.. - - -update_rq_clock (2 samples, 0.05%) - - - -squashfs_read_data (7 samples, 0.18%) - - - -read_pages (1 samples, 0.03%) - - - -do_nanosleep (1 samples, 0.03%) - - - -update_rq_clock (403 samples, 10.09%) -update_rq_clock - - -__queue_work (1 samples, 0.03%) - - - -pick_next_task_fair (14 samples, 0.35%) - - - -update_rq_clock (2 samples, 0.05%) - - - -pcpu_alloc (1 samples, 0.03%) - - - -d_alloc (1 samples, 0.03%) - - - -insert_work (1 samples, 0.03%) - - - -rcu_do_batch (7 samples, 0.18%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -run_timer_softirq (1 samples, 0.03%) - - - -exit_to_user_mode_prepare (8 samples, 0.20%) - - - -do_syscall_64 (1,917 samples, 48.01%) -do_syscall_64 - - -rcu_core_si (1 samples, 0.03%) - - - -tty_port_default_receive_buf (27 samples, 0.68%) - - - -input_handle_event (1 samples, 0.03%) - - - -ttm_bo_handle_move_mem (2 samples, 0.05%) - - - -update_rq_clock (1 samples, 0.03%) - - - -tick_sched_timer (1 samples, 0.03%) - - - -exit_mm (1 samples, 0.03%) - - - -tick_sched_handle (2 samples, 0.05%) - - - -vmw_thread_fn (8 samples, 0.20%) - - - -common_nsleep (4 samples, 0.10%) - - - -commit_tail (63 samples, 1.58%) - - - -__sysvec_call_function_single (1 samples, 0.03%) - - - -arch_do_signal_or_restart (75 samples, 1.88%) -a.. - - -do_open (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -__run_timers.part.0 (1 samples, 0.03%) - - - -cpu_startup_entry (6 samples, 0.15%) - - - -__fdget (1 samples, 0.03%) - - - -vmballoon_reset (1 samples, 0.03%) - - - -__wake_up_common_lock (1 samples, 0.03%) - - - -page_cache_sync_ra (2 samples, 0.05%) - - - -__cond_resched (3 samples, 0.08%) - - - -__sysvec_call_function_single (1 samples, 0.03%) - - - -__cond_resched (1 samples, 0.03%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -__vmw_fences_update (2 samples, 0.05%) - - - -_nohz_idle_balance.constprop.0.isra.0 (2 samples, 0.05%) - - - -schedule_hrtimeout_range (34 samples, 0.85%) - - - -update_rq_clock (3 samples, 0.08%) - - - -update_rq_clock (1 samples, 0.03%) - - - -rcu_gp_kthread (92 samples, 2.30%) -r.. - - -exit_to_user_mode_prepare (353 samples, 8.84%) -exit_to_user.. - - -call_timer_fn (1 samples, 0.03%) - - - -submit_bh_wbc (2 samples, 0.05%) - - - -io_schedule (4 samples, 0.10%) - - - -schedule (197 samples, 4.93%) -schedule - - -__softirqentry_text_start (1 samples, 0.03%) - - - -native_flush_tlb_multi (1 samples, 0.03%) - - - -futex_wait_queue_me (403 samples, 10.09%) -futex_wait_que.. - - -squashfs_cache_get (7 samples, 0.18%) - - - -update_rq_clock (1 samples, 0.03%) - - - -update_process_times (1 samples, 0.03%) - - - -common_interrupt (1 samples, 0.03%) - - - -native_safe_halt (7 samples, 0.18%) - - - -mutex_lock (61 samples, 1.53%) - - - -squashfs_readpage (2 samples, 0.05%) - - - -flush_smp_call_function_queue (24 samples, 0.60%) - - - -psmouse_handle_byte (1 samples, 0.03%) - - - -flush_work (17 samples, 0.43%) - - - -sysvec_call_function_single (1 samples, 0.03%) - - - -process_one_work (156 samples, 3.91%) -proc.. - - -new_sync_read (6 samples, 0.15%) - - - -_raw_spin_unlock_irqrestore (1 samples, 0.03%) - - - -do_group_exit (75 samples, 1.88%) -d.. - - -update_rq_clock (2 samples, 0.05%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -ep_poll_callback (1 samples, 0.03%) - - - -update_process_times (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -irqentry_exit_to_user_mode (119 samples, 2.98%) -ir.. - - -__hrtimer_run_queues (1 samples, 0.03%) - - - -_raw_spin_unlock_bh (1 samples, 0.03%) - - - -newidle_balance (1 samples, 0.03%) - - - -__writepage (2 samples, 0.05%) - - - -do_writepages (2 samples, 0.05%) - - - -native_safe_halt (6 samples, 0.15%) - - - -wb_writeback (2 samples, 0.05%) - - - -flush_smp_call_function_queue (1 samples, 0.03%) - - - -blk_mq_delay_run_hw_queue (1 samples, 0.03%) - - - -__x64_sys_futex (547 samples, 13.70%) -__x64_sys_futex - - -update_rq_clock (1 samples, 0.03%) - - - -squashfs_get_datablock (7 samples, 0.18%) - - - -evdev_events (1 samples, 0.03%) - - - -shmem_get_tree (1 samples, 0.03%) - - - -insert_work (15 samples, 0.38%) - - - -delayed_work_timer_fn (1 samples, 0.03%) - - - -asm_sysvec_call_function_single (1 samples, 0.03%) - - - -process_timeout (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -writeback_sb_inodes (2 samples, 0.05%) - - - -read_pages (8 samples, 0.20%) - - - -read_pages (2 samples, 0.05%) - - - -vmw_stdu_primary_plane_cleanup_fb (61 samples, 1.53%) - - - -sysvec_call_function_single (2 samples, 0.05%) - - - -__schedule (1 samples, 0.03%) - - - -run_rebalance_domains (2 samples, 0.05%) - - - -schedule (1 samples, 0.03%) - - - -handle_fasteoi_irq (1 samples, 0.03%) - - - -ksys_mmap_pgoff (1 samples, 0.03%) - - - -blkdev_writepage (2 samples, 0.05%) - - - -__alloc_percpu (1 samples, 0.03%) - - - -jbd2_journal_commit_transaction (4 samples, 0.10%) - - - -acpi_idle_enter (6 samples, 0.15%) - - - -vmw_fences_update (2 samples, 0.05%) - - - -__cond_resched (3 samples, 0.08%) - - - -submit_bio_wait_endio (2 samples, 0.05%) - - - -common_interrupt (1 samples, 0.03%) - - - -__sched_text_start (7 samples, 0.18%) - - - -vmw_stdu_primary_plane_atomic_update (1 samples, 0.03%) - - - -hrtimer_interrupt (1 samples, 0.03%) - - - -scsi_end_request (1 samples, 0.03%) - - - -page_cache_ra_unbounded (2 samples, 0.05%) - - - -alloc_pages (3 samples, 0.08%) - - - -squashfs_cache_get (1 samples, 0.03%) - - - -__wake_up_sync_key (1 samples, 0.03%) - - - -__hrtimer_run_queues (1 samples, 0.03%) - - - -call_timer_fn (1 samples, 0.03%) - - - -__x64_sys_mmap (1 samples, 0.03%) - - - -squashfs_xz_uncompress (1 samples, 0.03%) - - - -down_read (2 samples, 0.05%) - - - -tick_sched_timer (1 samples, 0.03%) - - - -do_wp_page (1 samples, 0.03%) - - - -__hrtimer_run_queues (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -do_read_fault (17 samples, 0.43%) - - - -input_pass_values.part.0 (1 samples, 0.03%) - - - -tick_sched_handle (1 samples, 0.03%) - - - -__run_timers.part.0 (1 samples, 0.03%) - - - -copy_process (2 samples, 0.05%) - - - -update_rq_clock (71 samples, 1.78%) - - - -dma_fence_signal_timestamp_locked (7 samples, 0.18%) - - - -schedule_hrtimeout_range_clock (34 samples, 0.85%) - - - -update_rq_clock (1 samples, 0.03%) - - - -cpuidle_idle_call (7 samples, 0.18%) - - - -asm_sysvec_call_function_single (2 samples, 0.05%) - - - -page_cache_ra_unbounded (1 samples, 0.03%) - - - -run_rebalance_domains (1 samples, 0.03%) - - - -do_sys_poll (53 samples, 1.33%) - - - -alloc_super (1 samples, 0.03%) - - - -sysvec_apic_timer_interrupt (2 samples, 0.05%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -swake_up_locked (2 samples, 0.05%) - - - -futex_wake (144 samples, 3.61%) -fute.. - - -exit_to_user_mode_prepare (119 samples, 2.98%) -ex.. - - -hrtimer_wakeup (1 samples, 0.03%) - - - -pick_next_task (1 samples, 0.03%) - - - -vmw_kms_cursor_post_execbuf (2 samples, 0.05%) - - - -__cond_resched (1 samples, 0.03%) - - - -__cond_resched (1 samples, 0.03%) - - - -update_rq_clock (181 samples, 4.53%) -updat.. - - -__x64_sys_readahead (1 samples, 0.03%) - - - -asm_common_interrupt (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (3 samples, 0.08%) - - - -input_event (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -evdev_events (1 samples, 0.03%) - - - -hrtimer_interrupt (1 samples, 0.03%) - - - -irq_exit_rcu (1 samples, 0.03%) - - - -blk_mq_do_dispatch_sched (1 samples, 0.03%) - - - -default_wake_function (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -lzma_main (1 samples, 0.03%) - - - -vmw_goal_waiter_add (1 samples, 0.03%) - - - -newidle_balance (14 samples, 0.35%) - - - -generic_smp_call_function_single_interrupt (2 samples, 0.05%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -__handle_irq_event_percpu (1 samples, 0.03%) - - - -exit_to_user_mode_loop (8 samples, 0.20%) - - - -update_rq_clock (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -__wake_up_common_lock (1 samples, 0.03%) - - - -__tty_check_change (1 samples, 0.03%) - - - -__x64_sys_poll (161 samples, 4.03%) -__x6.. - - -flush_to_ldisc (27 samples, 0.68%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -ptep_clear_flush (1 samples, 0.03%) - - - -filemap_get_pages (4 samples, 0.10%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -run_timer_softirq (2 samples, 0.05%) - - - -__hrtimer_run_queues (1 samples, 0.03%) - - - -rq_qos_wait (2 samples, 0.05%) - - - -squashfs_bio_read (3 samples, 0.08%) - - - -commit_work (63 samples, 1.58%) - - - -update_rq_clock (46 samples, 1.15%) - - - -irqentry_exit (353 samples, 8.84%) -irqentry_exit - - -__wait_for_common (3 samples, 0.08%) - - - -update_rq_clock (1 samples, 0.03%) - - - -vfs_fadvise (1 samples, 0.03%) - - - -irq_exit_rcu (1 samples, 0.03%) - - - -rest_init (9 samples, 0.23%) - - - -blk_mq_complete_request (2 samples, 0.05%) - - - -update_rq_clock (1 samples, 0.03%) - - - -run_rebalance_domains (7 samples, 0.18%) - - - -run_timer_softirq (1 samples, 0.03%) - - - -sysvec_apic_timer_interrupt (2 samples, 0.05%) - - - -__get_user_8 (1 samples, 0.03%) - - - -__writeback_inodes_wb (2 samples, 0.05%) - - - -n_tty_read (2 samples, 0.05%) - - - -sysvec_call_function_single (507 samples, 12.70%) -sysvec_call_functio.. - - -lookup_open.isra.0 (1 samples, 0.03%) - - - -_raw_spin_lock (1 samples, 0.03%) - - - -asm_sysvec_call_function_single (1 samples, 0.03%) - - - -update_rq_clock (2 samples, 0.05%) - - - -drm_atomic_helper_cleanup_planes (61 samples, 1.53%) - - - -__blk_mq_do_dispatch_sched (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -__wake_up_common (1 samples, 0.03%) - - - -ldsem_down_read (1 samples, 0.03%) - - - -exit_to_user_mode_loop (353 samples, 8.84%) -exit_to_user.. - - -psmouse_interrupt (1 samples, 0.03%) - - - -__schedule (1 samples, 0.03%) - - - -__schedule (1 samples, 0.03%) - - - -__sysvec_call_function_single (1 samples, 0.03%) - - - -update_rq_clock (15 samples, 0.38%) - - - -blk_mq_sched_dispatch_requests (1 samples, 0.03%) - - - -generic_smp_call_function_single_interrupt (1 samples, 0.03%) - - - -update_process_times (1 samples, 0.03%) - - - -get_page_from_freelist (2 samples, 0.05%) - - - -wake_up_process (1 samples, 0.03%) - - - -update_rq_clock (4 samples, 0.10%) - - - -schedule_timeout (72 samples, 1.80%) -s.. - - -tick_sched_handle (1 samples, 0.03%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -do_exit (75 samples, 1.88%) -d.. - - -sysvec_call_function_single (1 samples, 0.03%) - - - -__run_timers.part.0 (16 samples, 0.40%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -__blk_mq_end_request (1 samples, 0.03%) - - - -irq_thread (205 samples, 5.13%) -irq_th.. - - -wp_page_copy (1 samples, 0.03%) - - - -update_rq_clock (3 samples, 0.08%) - - - -default_wake_function (1 samples, 0.03%) - - - -block_write_full_page (2 samples, 0.05%) - - - -input_to_handler (1 samples, 0.03%) - - - -wake_up_process (15 samples, 0.38%) - - - -wake_up_process (1 samples, 0.03%) - - - -wake_up_process (2 samples, 0.05%) - - - -blk_complete_reqs (3 samples, 0.08%) - - - -pick_next_task_fair (1 samples, 0.03%) - - - -__x64_sys_timerfd_settime (1 samples, 0.03%) - - - -update_rq_clock (2 samples, 0.05%) - - - -tick_sched_timer (2 samples, 0.05%) - - - -finish_task_switch.isra.0 (4 samples, 0.10%) - - - -asm_sysvec_call_function_single (1 samples, 0.03%) - - - -update_rq_clock (7 samples, 0.18%) - - - -ondemand_readahead (2 samples, 0.05%) - - - -input_pass_values.part.0 (1 samples, 0.03%) - - - -update_rq_clock (2 samples, 0.05%) - - - -__sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -entry_SYSCALL_64_after_hwframe (1,917 samples, 48.01%) -entry_SYSCALL_64_after_hwframe - - -cpuidle_enter_state (7 samples, 0.18%) - - - -__page_cache_alloc (3 samples, 0.08%) - - - -handle_edge_irq (1 samples, 0.03%) - - - -rseq_ip_fixup (1 samples, 0.03%) - - - -newidle_balance (1 samples, 0.03%) - - - -__cond_resched (1 samples, 0.03%) - - - -__run_timers.part.0 (1 samples, 0.03%) - - - -page_cache_async_ra (6 samples, 0.15%) - - - -irq_exit_rcu (4 samples, 0.10%) - - - -update_rq_clock (14 samples, 0.35%) - - - -irq_exit_rcu (1 samples, 0.03%) - - - -update_rq_clock (8 samples, 0.20%) - - - -read_tsc (1 samples, 0.03%) - - - -schedule (4 samples, 0.10%) - - - -serio_interrupt (1 samples, 0.03%) - - - -handle_edge_irq (1 samples, 0.03%) - - - -__writeback_single_inode (2 samples, 0.05%) - - - -generic_smp_call_function_single_interrupt (154 samples, 3.86%) -gene.. - - -update_rq_clock (2 samples, 0.05%) - - - -do_mmap (1 samples, 0.03%) - - - -wake_up_process (1 samples, 0.03%) - - - -run_rebalance_domains (3 samples, 0.08%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -vfs_read (8 samples, 0.20%) - - - -update_rq_clock (22 samples, 0.55%) - - - -__hrtimer_run_queues (15 samples, 0.38%) - - - -n_tty_receive_buf2 (27 samples, 0.68%) - - - -generic_fadvise (1 samples, 0.03%) - - - -wake_up_process (7 samples, 0.18%) - - - -generic_smp_call_function_single_interrupt (1 samples, 0.03%) - - - -__queue_work (1 samples, 0.03%) - - - -all (3,993 samples, 100%) - - - -ksys_read (9 samples, 0.23%) - - - -schedule (72 samples, 1.80%) -s.. - - -do_new_mount (1 samples, 0.03%) - - - -__receive_buf (27 samples, 0.68%) - - - -sysvec_call_function_single (17 samples, 0.43%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -update_rq_clock (1 samples, 0.03%) - - - -__softirqentry_text_start (1 samples, 0.03%) - - - -bio_endio (2 samples, 0.05%) - - - -drm_atomic_helper_crtc_destroy_state (1 samples, 0.03%) - - - -wake_up_process (1 samples, 0.03%) - - - -asm_sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -update_rq_clock (804 samples, 20.14%) -update_rq_clock - - -__handle_irq_event_percpu (1 samples, 0.03%) - - - -irq_thread_fn (8 samples, 0.20%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -__block_write_full_page (2 samples, 0.05%) - - - -kmem_cache_alloc_trace (1 samples, 0.03%) - - - -update_rq_clock (2 samples, 0.05%) - - - -sysvec_call_function_single (1 samples, 0.03%) - - - -common_interrupt (1 samples, 0.03%) - - - -wake_up_process (1 samples, 0.03%) - - - -generic_smp_call_function_single_interrupt (1 samples, 0.03%) - - - -rcu_do_batch (1 samples, 0.03%) - - - -__queue_work (15 samples, 0.38%) - - - -mutex_unlock (1 samples, 0.03%) - - - -squashfs_decompress (1 samples, 0.03%) - - - -file_tty_write.constprop.0 (1 samples, 0.03%) - - - -__sysvec_apic_timer_interrupt (15 samples, 0.38%) - - - -kmem_cache_alloc (1 samples, 0.03%) - - - -schedule_hrtimeout_range_clock (1 samples, 0.03%) - - - -irqentry_exit_to_user_mode (8 samples, 0.20%) - - - -sysvec_apic_timer_interrupt (1 samples, 0.03%) - - - -update_rq_clock (15 samples, 0.38%) - - - -__do_fault (17 samples, 0.43%) - - - -generic_smp_call_function_single_interrupt (1 samples, 0.03%) - - - -irqentry_exit (9 samples, 0.23%) - - - -mmap_region (1 samples, 0.03%) - - - -blk_mq_complete_request_remote (2 samples, 0.05%) - - - -kmem_cache_alloc_trace (1 samples, 0.03%) - - - -wake_up_process (2 samples, 0.05%) - - - -update_rq_clock (2 samples, 0.05%) - - - -update_rq_clock (20 samples, 0.50%) - - - -vmw_ttm_populate.part.0 (2 samples, 0.05%) - - - -rcu_work_rcufn (1 samples, 0.03%) - - - - From 9989514bd2ff8ab8442327eb3d014c35d13e1446 Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Sun, 10 Mar 2024 05:16:00 +0000 Subject: [PATCH 06/55] modify doc Signed-off-by: LiuLingze --- eBPF_Supermarket/Stack_Analyser/README.md | 11 +++++--- .../Stack_Analyser/exporter/README.md | 26 +++++++++++++++++-- .../Stack_Analyser/exporter/main.go | 1 + 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/eBPF_Supermarket/Stack_Analyser/README.md b/eBPF_Supermarket/Stack_Analyser/README.md index 37e2033f5..6ba720da4 100644 --- a/eBPF_Supermarket/Stack_Analyser/README.md +++ b/eBPF_Supermarket/Stack_Analyser/README.md @@ -68,8 +68,7 @@ $ git submodule update --init --recursive $ apt install clang libelf1 libelf-dev zlib1g-dev ``` -g++-10以上 -clang-12以上 +g++-10以上,clang-12以上 # 使用方法 @@ -105,6 +104,10 @@ commands: OK ``` +## 发送到Pyroscope + +请阅读[`exporter/README.md`](exporter/README.md)。 + # 目录描述 - include:各种定义。 @@ -112,4 +115,6 @@ OK - src:各种实现。 - src/bpf:eBPF程序的代码和其包装类的实现。 - exporter:使用Golang开发的数据推送程序,将采集到的调用栈数据推送到Pyroscope服务器,获取更强的数据存储和可视化性能。 -- main.cpp:负责参数解析、配置、调用栈数据收集器管理和子进程管理。 \ No newline at end of file +- main.cpp:负责参数解析、配置、调用栈数据收集器管理和子进程管理。 +- libbpf-bootstrap: 项目依赖的libbpf及相关工具源代码,方便移植。 +- new_bpf.sh:初始化新的采集能力的脚本,详情请参考`框架使用说明.md`。 \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/exporter/README.md b/eBPF_Supermarket/Stack_Analyser/exporter/README.md index 6b628d2e4..911164863 100644 --- a/eBPF_Supermarket/Stack_Analyser/exporter/README.md +++ b/eBPF_Supermarket/Stack_Analyser/exporter/README.md @@ -1,3 +1,25 @@ -# 数据发送器 +# 功能描述 -适用于Pyroscope服务器的数据发送程序,程序通过监听标准输入来获取调用栈数据,输入格式和libbpf框架实现的Stack_Analyzer输出格式一致,可通过管道配合Stack_Analyer使用,将Stack_Analyzer的数据发送到Pyroscope服务器获取更强的数据存储和可视化能力。 \ No newline at end of file +适用于Pyroscope服务器的数据发送程序,程序通过监听标准输入来获取调用栈数据,输入格式与stack_analyzer工具输出格式一致,可通过管道配合stack_analyer使用,将stack_analyzer的数据发送到Pyroscope服务器获取更强的数据存储和可视化能力。 + +# 使用方法 + +若在该文件所在目录exporter下进行。 + +## 构建 + +```shell +go build +``` + +## 命令参数 + +```shell +./exporter --help +``` + +## 使用方法 + +```shell +sudo ../stack_analyzer [option..] | ./exporter +``` \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/exporter/main.go b/eBPF_Supermarket/Stack_Analyser/exporter/main.go index ca1845725..dbc09b20b 100644 --- a/eBPF_Supermarket/Stack_Analyser/exporter/main.go +++ b/eBPF_Supermarket/Stack_Analyser/exporter/main.go @@ -54,6 +54,7 @@ var ( ) func main() { + flag.Parse() reader = *bufio.NewReader(os.Stdin) logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) // 创建画像数据发送信道 From 325166cee4ea692a3d5c39d224eb90393d7074b2 Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Sun, 10 Mar 2024 05:41:32 +0000 Subject: [PATCH 07/55] modify submodule Signed-off-by: LiuLingze --- eBPF_Supermarket/Stack_Analyser/libbpf-bootstrap | 1 + 1 file changed, 1 insertion(+) create mode 160000 eBPF_Supermarket/Stack_Analyser/libbpf-bootstrap diff --git a/eBPF_Supermarket/Stack_Analyser/libbpf-bootstrap b/eBPF_Supermarket/Stack_Analyser/libbpf-bootstrap new file mode 160000 index 000000000..b0c8234df --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/libbpf-bootstrap @@ -0,0 +1 @@ +Subproject commit b0c8234dfb8f31eb12c99b26bb2bec96eb76aff3 From 1def496bb50bf77bc6b2a5ccc06c75c4fc52ef10 Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Sun, 10 Mar 2024 05:58:19 +0000 Subject: [PATCH 08/55] modify ignore Signed-off-by: LiuLingze --- .gitignore | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c68ed5603..21ee951f5 100644 --- a/.gitignore +++ b/.gitignore @@ -63,4 +63,14 @@ eBPF_Supermarket/kvm_watcher/**/temp* # eBPF_proc_image eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/.output/* -eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/proc_image \ No newline at end of file +eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/proc_image + +# libbpf_bootstrap +.output + +# eBPF skeletons +*.skel.h + +# Stack_Analyser +stack_analyzer +exporter \ No newline at end of file From 07c6e5eb01b2d3379c915dd2d0dcd47658cde180 Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Sun, 10 Mar 2024 06:00:47 +0000 Subject: [PATCH 09/55] modify ignore Signed-off-by: LiuLingze --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 21ee951f5..5342e69b3 100644 --- a/.gitignore +++ b/.gitignore @@ -72,5 +72,5 @@ eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/proc_image *.skel.h # Stack_Analyser -stack_analyzer -exporter \ No newline at end of file +eBPF_Supermarket/Stack_Analyser/stack_analyzer +eBPF_Supermarket/Stack_Analyser/exporter/exporter \ No newline at end of file From e903f92b9057a997f21f6a588e77e22bd46418dc Mon Sep 17 00:00:00 2001 From: syxl-time <953879556@qq.com> Date: Fri, 15 Mar 2024 21:42:33 +0800 Subject: [PATCH 10/55] =?UTF-8?q?mem=5Fwatcher:=E5=88=A0=E9=99=A4=E5=86=97?= =?UTF-8?q?=E4=BD=99=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../applications/mem_watcher/Makefile | 2 +- .../mem_watcher/mem_watcher.bpf.c | 135 +----- .../applications/mem_watcher/mem_watcher.c | 50 +- .../applications/mem_watcher/mem_watcher.h | 73 +-- .../mem_watcher/mem_watcher_bak.c | 450 ------------------ .../applications/mem_watcher/paf.bpf.c | 2 +- .../applications/mem_watcher/paf.c | 214 +-------- .../applications/mem_watcher/paf.h | 59 --- .../applications/mem_watcher/pr.bpf.c | 2 +- .../applications/mem_watcher/pr.c | 180 +------ .../applications/mem_watcher/pr.h | 17 - .../applications/mem_watcher/procstat.bpf.c | 2 +- .../applications/mem_watcher/procstat.c | 206 +------- .../applications/mem_watcher/procstat.h | 28 -- .../applications/mem_watcher/sysstat.bpf.c | 2 +- .../applications/mem_watcher/sysstat.c | 181 +------ .../applications/mem_watcher/sysstat.h | 48 -- 17 files changed, 59 insertions(+), 1592 deletions(-) delete mode 100644 eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher_bak.c delete mode 100644 eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/paf.h delete mode 100644 eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/pr.h delete mode 100644 eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/procstat.h delete mode 100644 eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/sysstat.h diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/Makefile b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/Makefile index 76848f8c7..b0d796afc 100644 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/Makefile +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/Makefile @@ -30,7 +30,7 @@ CARGO ?= $(shell which cargo) ifeq ($(strip $(CARGO)),) BZS_APPS := else -BZS_APPS := profile +BZS_APPS := APPS += $(BZS_APPS) # Required by libblazesym ALL_LDFLAGS += -lrt -ldl -lpthread -lm diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.bpf.c b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.bpf.c index 0bc932dc0..2872e867e 100644 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.bpf.c +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.bpf.c @@ -11,137 +11,4 @@ #include #include #include -#include "mem_watcher.h" - -char LICENSE[] SEC("license") = "Dual BSD/GPL"; - -struct { - __uint(type, BPF_MAP_TYPE_RINGBUF); - __uint(max_entries, 256 * 1024); -} rb SEC(".maps"); - -pid_t user_pid = 0; - -SEC("kprobe/get_page_from_freelist") -int BPF_KPROBE(get_page_from_freelist, gfp_t gfp_mask, unsigned int order, int alloc_flags, const struct alloc_context *ac) -{ - struct event *e; - unsigned long *t, y; - int a; - pid_t pid = bpf_get_current_pid_tgid() >> 32; - if (pid == user_pid) - return 0; - e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); - if (!e) - return 0; - y = BPF_CORE_READ(ac, preferred_zoneref, zone, watermark_boost); - t = BPF_CORE_READ(ac, preferred_zoneref, zone, _watermark); - - e->present = BPF_CORE_READ(ac, preferred_zoneref, zone, present_pages); - e->min = t[0] + y; - e->low = t[1] + y; - e->high = t[2] + y; - e->flag = (int)gfp_mask; - - bpf_ringbuf_submit(e, 0); - return 0; -} - -SEC("kprobe/shrink_page_list") -int BPF_KPROBE(shrink_page_list, struct list_head *page_list, struct pglist_data *pgdat, struct scan_control *sc) -{ - struct event *e; - unsigned long y; - unsigned int *a; - pid_t pid = bpf_get_current_pid_tgid() >> 32; - if (pid == user_pid) - return 0; - e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); - if (!e) - return 0; - e->reclaim = BPF_CORE_READ(sc, nr_to_reclaim);//要回收页面 - y = BPF_CORE_READ(sc, nr_reclaimed); - e->reclaimed = y;//已经回收的页面 - a =(unsigned int *)(&y + 1); - e->unqueued_dirty = *(a + 1);//还没开始回写和还没在队列等待的脏页 - e->congested = *(a + 2);//正在块设备上回写的页面,含写入交换空间的页面 - e->writeback = *(a + 3);//正在回写的页面 - - - - bpf_ringbuf_submit(e, 0); - return 0; -} - -SEC("kprobe/finish_task_switch") -int BPF_KPROBE(finish_task_switch, struct task_struct *prev) { - struct event *e; - struct mm_rss_stat rss = {}; - struct mm_struct *mms; - long long *t; - pid_t pid = bpf_get_current_pid_tgid() >> 32; - if (pid == user_pid) - return 0; - e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); - if (!e) - return 0; - - e->pid = BPF_CORE_READ(prev, pid); - e->vsize = BPF_CORE_READ(prev, mm, total_vm); - e->Vdata = BPF_CORE_READ(prev, mm, data_vm); - e->Vstk = BPF_CORE_READ(prev, mm, stack_vm); - e->nvcsw = BPF_CORE_READ(prev, nvcsw); - e->nivcsw = BPF_CORE_READ(prev, nivcsw); - - rss = BPF_CORE_READ(prev, mm, rss_stat); - t = (long long *)(rss.count); - e->rssfile = *t; - e->rssanon = *(t + 1); - e->vswap = *(t + 2); - e->rssshmem = *(t + 3); - e->size = *t + *(t + 1) + *(t + 3); - - bpf_ringbuf_submit(e, 0); - return 0; -} - -SEC("kprobe/get_page_from_freelist") -int BPF_KPROBE(get_page_from_freelist_second, gfp_t gfp_mask, unsigned int order, int alloc_flags, const struct alloc_context *ac) { - struct event *e; - unsigned long *t; - pid_t pid = bpf_get_current_pid_tgid() >> 32; - if (pid == user_pid) - return 0; - e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); - if (!e) - return 0; - - // e->present = BPF_CORE_READ(ac, preferred_zoneref, zone, zone_pgdat, node_spanned_pages); - t = (unsigned long *)BPF_CORE_READ(ac, preferred_zoneref, zone, zone_pgdat, vm_stat); - // t = (unsigned long *)BPF_CORE_READ(ac, preferred_zoneref, zone, vm_stat); - e->anon_inactive = t[0] * 4; - e->anon_active = t[1] * 4; - e->file_inactive = t[2] * 4; - e->file_active = t[3] * 4; - e->unevictable = t[4] * 4; - - - e->file_dirty = t[20] * 4; - e->writeback = t[21] * 4; - e->anon_mapped = t[17] * 4; - e->file_mapped = t[18] * 4; - e->shmem = t[23] * 4; - - e->slab_reclaimable = t[5] * 4; - e->kernel_misc_reclaimable = t[29] * 4; - e->slab_unreclaimable = t[6] * 4; - - e->unstable_nfs = t[27] * 4; - e->writeback_temp = t[22] * 4; - - e->anon_thps = t[26] * 4; - e->shmem_thps = t[24] * 4; - e->pmdmapped = t[25] * 4; - bpf_ringbuf_submit(e, 0); - return 0; -} +#include "mem_watcher.h" \ No newline at end of file diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.c b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.c index 4a0ce9b85..f241cd97a 100644 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.c +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.c @@ -24,14 +24,11 @@ #include #include #include -#include "paf.h" #include "paf.skel.h" -#include "pr.h" #include "pr.skel.h" -#include "procstat.h" #include "procstat.skel.h" -#include "sysstat.h" #include "sysstat.skel.h" +#include "mem_watcher.h" static struct env { int time; @@ -130,14 +127,6 @@ static void sig_handler(int sig) { exiting = true; } -static void msleep(long secs) { - struct timeval tval; - - tval.tv_sec = secs / 1000; - tval.tv_usec = (secs * 1000) % 1000000; - select(0, NULL, NULL, NULL, &tval); -} - /* static char* flags(int flag) { @@ -180,13 +169,7 @@ static int handle_event_paf(void *ctx, void *data, size_t data_sz) { printf("%-8lu %-8lu %-8lu %-8lu %-8x\n", e->min, e->low, e->high, e->present, e->flag); - /* 睡眠会导致程序无法终止,所以需要注释掉这个代码块 */ - // if (env.time != 0) { - // msleep(env.time); - // } - // else { - // msleep(1000); - // } + return 0; } @@ -202,15 +185,7 @@ static int handle_event_pr(void *ctx, void *data, size_t data_sz) { printf("%-8lu %-8lu %-8u %-8u %-8u\n", e->reclaim, e->reclaimed, e->unqueued_dirty, e->congested, e->writeback); - /* 睡眠会导致程序无法终止,所以需要注释掉这个代码块 */ - // if (env.time != 0) - // { - // msleep(env.time); - // } - // else - // { - // msleep(1000); - // } + return 0; } @@ -237,15 +212,7 @@ static int handle_event_procstat(void *ctx, void *data, size_t data_sz) { else printf("%-8s %-8d %-8ld %-8lld %-8lld %-8lld\n", ts, e->pid, e->size, e->rssanon, e->rssfile, e->rssshmem); } - /* 睡眠会导致程序无法终止,所以需要注释掉这个代码块 */ - // if (env.time != 0) - // { - // msleep(env.time); - // } - // else - // { - // msleep(1000); - // } + return 0; } @@ -264,15 +231,6 @@ static int handle_event_sysstat(void *ctx, void *data, size_t data_sz) { else printf("%-8lu %-8lu %-8lu %-8lu %-8lu %-8lu %-8lu %-8lu %-8lu %-8lu %-8lu %-8lu\n", e->anon_active + e->file_active, e->file_inactive + e->anon_inactive, e->anon_active, e->anon_inactive, e->file_active, e->file_inactive, e->unevictable, e->file_dirty, e->writeback, e->anon_mapped, e->file_mapped, e->shmem); - /* 睡眠会导致程序无法终止,所以需要注释掉这个代码块 */ - // if (env.time != 0) - // { - // msleep(env.time); - // } - // else - // { - // msleep(1000); - // } return 0; } diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.h b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.h index d6f3c3ec2..778767287 100644 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.h +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.h @@ -43,70 +43,75 @@ __GFP_NOMEMALLOC | __GFP_NOWARN) & ~__GFP_RECLAIM) #define GFP_TRANSHUGE (GFP_TRANSHUGE_LIGHT | __GFP_DIRECT_RECLAIM) - -struct event { - unsigned long reclaim; - unsigned long reclaimed; - unsigned int unqueued_dirty; - unsigned int congested; - unsigned int writeback; - - unsigned long min; +struct paf_event { + unsigned long min; unsigned long low; unsigned long high; unsigned long present; unsigned long protection; int flag; +}; +struct pr_event { + unsigned long reclaim; + unsigned long reclaimed; + unsigned int unqueued_dirty; + unsigned int congested; + unsigned int writeback; +}; + +struct procstat_event { /*进程内存状态报告*/ pid_t pid; - long nvcsw; - long nivcsw; - long vsize; //虚拟内存 - long size; //物理内存 - long long rssanon; //匿名页面 - long long rssfile; //文件页面 - long long rssshmem; //共享页面 - long long vswap; //交换页面 - long long Hpages; //hugetlbPages - long Vdata; //Private data segments - long Vstk; //User stack + long nvcsw; + long nivcsw; + long vsize; //虚拟内存 + long size; //物理内存 + long long rssanon; //匿名页面 + long long rssfile; //文件页面 + long long rssshmem; //共享页面 + long long vswap; //交换页面 + long long Hpages; //hugetlbPages + long Vdata; //Private data segments + long Vstk; //User stack long long VPTE; +}; +struct sysstat_event { /*系统内存状态报告*/ - //unsigned long present; - unsigned long anon_inactive;//0 - unsigned long anon_active;//1 - unsigned long file_inactive;//2 - unsigned long file_active;//3 - unsigned long unevictable;//不可回收页面 + unsigned long present; + unsigned long anon_inactive; // 0 + unsigned long anon_active; // 1 + unsigned long file_inactive; // 2 + unsigned long file_active; // 3 + unsigned long unevictable; // 不可回收页面 unsigned long slab_reclaimable; unsigned long slab_unreclaimable; - unsigned long anon_isolated; //匿名隔离页面 - unsigned long file_isolated; //文件隔离页面 + unsigned long anon_isolated; // 匿名隔离页面 + unsigned long file_isolated; // 文件隔离页面 - unsigned long working_nodes;//12 + unsigned long working_nodes; // 12 unsigned long working_refault; unsigned long working_activate; unsigned long working_restore; unsigned long working_nodereclaim; - unsigned long anon_mapped;//17 + unsigned long anon_mapped; // 17 unsigned long file_mapped; - unsigned long file_pages;//19 + unsigned long file_pages; // 19 unsigned long file_dirty; - //unsigned long writeback; + unsigned long writeback; unsigned long writeback_temp; - unsigned long shmem;//共享内存23 + unsigned long shmem; // 共享内存23 unsigned long shmem_thps; unsigned long pmdmapped; unsigned long anon_thps; unsigned long unstable_nfs; unsigned long vmscan_write; unsigned long vmscan_immediate; - + unsigned long diried; unsigned long written; unsigned long kernel_misc_reclaimable; diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher_bak.c b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher_bak.c deleted file mode 100644 index 9346564c3..000000000 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher_bak.c +++ /dev/null @@ -1,450 +0,0 @@ -// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) -/* Copyright (c) 2020 Facebook */ -#include -#include -#include -#include -#include -#include -#include "mem_watcher.h" -#include "mem_watcher.skel.h" -#include -#include - -#define GFP_ATOMIC 0x -static struct env -{ - int time; - bool paf; - bool pr; - bool procstat; - bool sysstat; - - long choose_pid; - bool rss; -} env = { - .time = 0, - .paf = false, - .pr = false, - .procstat = false, - .sysstat = false, - .rss = false, -}; - -const char argp_program_doc[] = "mem wacher is in use ....\n"; - -static const struct argp_option opts[] = { - {"time", 't', "TIME-SEC", 0, "Max Running Time(0 for infinite)", 3}, - {0, 0, 0, 0, "select function:", 1}, - {"paf", 'a', 0, 0, "print paf (内存页面状态报告)"}, - {"pr", 'p', 0, 0, "print pr (页面回收状态报告)"}, - {"procstat", 'r', 0, 0, "print procstat (进程内存状态报告)"}, - {"sysstat", 's', 0, 0, "print sysstat (系统内存状态报告)"}, - - {0, 0, 0, 0, "additional function:", 2}, - {"choose_pid", 'P', "PID", 0, "选择进程号打印"}, - {"Rss", 'R', NULL, 0, "打印进程页面"}, - - {NULL, 'h', NULL, OPTION_HIDDEN, "show the full help", 4}, - {0}, -}; - -static error_t parse_arg(int key, char *arg, struct argp_state *state) -{ - switch (key) - { - case 't': - env.time = strtol(arg, NULL, 10); - if (env.time) - alarm(env.time); - break; - case 'a': - env.paf = true; - break; - case 'p': - env.pr = true; - break; - case 'r': - env.procstat = true; - break; - case 's': - env.sysstat = true; - break; - case 'h': - argp_state_help(state, stderr, ARGP_HELP_STD_HELP); - break; - case 'P': - env.choose_pid = strtol(arg, NULL, 10); - break; - case 'R': - env.rss = true; - break; - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -static const struct argp argp = { - .options = opts, - .parser = parse_arg, - .doc = argp_program_doc, -}; - -static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) -{ - return vfprintf(stderr, format, args); -} - -static volatile bool exiting = false; - -static void sig_handler(int sig) -{ - exiting = true; -} - -static void msleep(long secs) -{ - struct timeval tval; - - tval.tv_sec = secs / 1000; - tval.tv_usec = (secs * 1000) % 1000000; - select(0, NULL, NULL, NULL, &tval); -} - -/* -static char* flags(int flag) -{ - if(flag & GFP_ATOMIC) - return "GFP_ATOMIC"; - if(flag & GFP_KERNEL) - return "GFP_KERNEL"; - if(flag & GFP_KERNEL_ACCOUNT) - return "GFP_KERNEL_ACCOUNT"; - if(flag & GFP_NOWAIT) - return "GFP_NOWAIT"; - if(flag & GFP_NOIO ) - return "GFP_NOIO "; - if(flag & GFP_NOFS) - return "GFP_NOFS"; - if(flag & GFP_USER) - return "GFP_USER"; - if(flag & GFP_DMA) - return "GFP_DMA"; - if(flag & GFP_DMA32) - return "GFP_DMA32"; - if(flag & GFP_HIGHUSER) - return "GFP_HIGHUSER"; - if(flag & GFP_HIGHUSER_MOVABLE) - return "GFP_HIGHUSER_MOVABLE"; - if(flag & GFP_TRANSHUGE_LIGHT) - return "GFP_TRANSHUGE_LIGHT"; - return; -} -*/ -static int handle_event_paf(void *ctx, void *data, size_t data_sz) -{ - const struct event *e = data; - struct tm *tm; - char ts[32]; - time_t t; - - time(&t); - tm = localtime(&t); - strftime(ts, sizeof(ts), "%H:%M:%S", tm); - - printf("%-8lu %-8lu %-8lu %-8lu %-8x\n", - e->min, e->low, e->high, e->present, e->flag); - /* 睡眠会导致程序无法终止,所以需要注释掉这个代码块 */ - // if (env.time != 0) { - // msleep(env.time); - // } - // else { - // msleep(1000); - // } - return 0; -} - -static int handle_event_pr(void *ctx, void *data, size_t data_sz) -{ - const struct event *e = data; - struct tm *tm; - char ts[32]; - time_t t; - - time(&t); - tm = localtime(&t); - strftime(ts, sizeof(ts), "%H:%M:%S", tm); - - printf("%-8lu %-8lu %-8u %-8u %-8u\n", - e->reclaim, e->reclaimed, e->unqueued_dirty, e->congested, e->writeback); - /* 睡眠会导致程序无法终止,所以需要注释掉这个代码块 */ - // if (env.time != 0) - // { - // msleep(env.time); - // } - // else - // { - // msleep(1000); - // } - return 0; -} - -static int handle_event_procstat(void *ctx, void *data, size_t data_sz) -{ - const struct event *e = data; - struct tm *tm; - char ts[32]; - time_t t; - - time(&t); - tm = localtime(&t); - strftime(ts, sizeof(ts), "%H:%M:%S", tm); - - if (env.choose_pid) - { - if (e->pid == env.choose_pid) - { - if (env.rss == true) - printf("%-8s %-8d %-8ld %-8ld %-8ld %-8lld %-8lld\n", ts, e->pid, e->vsize, e->Vdata, e->Vstk, e->VPTE, e->vswap); - else - printf("%-8s %-8d %-8ld %-8lld %-8lld %-8lld\n", ts, e->pid, e->size, e->rssanon, e->rssfile, e->rssshmem); - } - } - else - { - if (env.rss == true) - printf("%-8s %-8d %-8ld %-8ld %-8ld %-8lld %-8lld\n", ts, e->pid, e->vsize, e->Vdata, e->Vstk, e->VPTE, e->vswap); - else - printf("%-8s %-8d %-8ld %-8lld %-8lld %-8lld\n", ts, e->pid, e->size, e->rssanon, e->rssfile, e->rssshmem); - } - /* 睡眠会导致程序无法终止,所以需要注释掉这个代码块 */ - // if (env.time != 0) - // { - // msleep(env.time); - // } - // else - // { - // msleep(1000); - // } - // return 0; -} - -static int handle_event_sysstat(void *ctx, void *data, size_t data_sz) -{ - const struct event *e = data; - struct tm *tm; - char ts[32]; - time_t t; - - time(&t); - tm = localtime(&t); - strftime(ts, sizeof(ts), "%H:%M:%S", tm); - - printf("+----------+----------+----------+----------+----------+----------+----------+\n"); - printf("|%-10s|%-10s|%-10s|%-10s|%-10s|%-10s|%-10s|\n", - "ACTIVE", "INACTVE", "ANON_ACT", "ANON_INA", "FILE_ACT", "FILE_INA", "UNEVICT"); - printf("|%-10lu|%-10lu|%-10lu|%-10lu|%-10lu|%-10lu|%-10lu|\n", - e->anon_active + e->file_active, e->file_inactive + e->anon_inactive, e->anon_active, e->anon_inactive, e->file_active, e->file_inactive, e->unevictable); - printf("+----------+----------+----------+----------+----------+----------+----------+\n"); - - printf("|%-10s|%-10s|%-10s|%-10s|%-10s|\n", - "DIRTY", "WRITEBK", "ANONMAP", "FILEMAP", "SHMEM"); - printf("|%-10lu|%-10lu|%-10lu|%-10lu|%-10lu|\n", - e->file_dirty, e->writeback, e->anon_mapped, e->file_mapped, e->shmem); - printf("+----------+----------+----------+----------+----------+\n"); - - printf("|%-10s|%-10s|%-10s|%-10s|%-10s|\n", - "RECLM+KMR", "RECLM+URE", "RECLMAB", "UNRECLMA", "UNSTABLE"); - printf("|%-10lu|%-10lu|%-10lu|%-10lu|%-10lu|\n", - e->slab_reclaimable + e->kernel_misc_reclaimable, e->slab_reclaimable + e->slab_unreclaimable, e->slab_reclaimable, e->slab_unreclaimable, e->unstable_nfs); - printf("+----------+----------+----------+----------+----------+\n"); - - printf("|%-10s|%-10s|%-10s|%-10s|\n", - "WRITEBK_T", "ANON_THP", "SHMEM_THP", "PMDMAPP"); - printf("|%-10lu|%-10lu|%-10lu|%-10lu|\n", - e->writeback_temp, e->anon_thps, e->shmem_thps, e->pmdmapped); - printf("+----------+----------+----------+----------+\n"); - /* 睡眠会导致程序无法终止,所以需要注释掉这个代码块 */ - // if (env.time != 0) - // { - // msleep(env.time); - // } - // else - // { - // msleep(1000); - // } - return 0; -} - -pid_t own_pid; - -int main(int argc, char **argv) -{ - struct ring_buffer *rb = NULL; - struct mem_watcher_bpf *skel; - - int err; - err = argp_parse(&argp, argc, argv, 0, NULL, NULL); - if (err) - return err; - own_pid = getpid(); - libbpf_set_strict_mode(LIBBPF_STRICT_ALL); - /* Set up libbpf errors and debug info callback */ - libbpf_set_print(libbpf_print_fn); - - /* Cleaner handling of Ctrl-C */ - signal(SIGINT, sig_handler); - signal(SIGTERM, sig_handler); - signal(SIGALRM, sig_handler); - - /* Load and verify BPF application */ - skel = mem_watcher_bpf__open(); - if (!skel) - { - fprintf(stderr, "Failed to open and load BPF skeleton\n"); - return 1; - } - skel->bss->user_pid = own_pid; - /* Load & verify BPF programs */ - err = mem_watcher_bpf__load(skel); - if (err) - { - fprintf(stderr, "Failed to load and verify BPF skeleton\n"); - goto cleanup; - } - - /* Attach tracepoints */ - err = mem_watcher_bpf__attach(skel); - if (err) - { - fprintf(stderr, "Failed to attach BPF skeleton\n"); - goto cleanup; - } - - if (env.paf) - { - rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), handle_event_paf, NULL, NULL); - if (!rb) - { - err = -1; - fprintf(stderr, "Failed to create ring buffer\n"); - goto cleanup; - } - printf("%-8s %-8s %-8s %-8s %-8s\n", "MIN", "LOW", "HIGH", "PRESENT", "FLAG"); - } - else if (env.pr) - { - rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), handle_event_pr, NULL, NULL); - if (!rb) - { - err = -1; - fprintf(stderr, "Failed to create ring buffer\n"); - goto cleanup; - } - printf("%-8s %-8s %-8s %-8s %-8s\n", "RECLAIM", "RECLAIMED", "UNQUEUE", "CONGESTED", "WRITEBACK"); - } - else if (env.procstat) - { - rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), handle_event_procstat, NULL, NULL); - if (!rb) - { - err = -1; - fprintf(stderr, "Failed to create ring buffer\n"); - goto cleanup; - } - if (env.rss == true) - { - printf("%-8s %-8s %-8s %-8s %-8s %-8s %-8s\n", "TIME", "PID", "VMSIZE", "VMDATA", "VMSTK", "VMPTE", "VMSWAP"); - } - else - { - printf("%-8s %-8s %-8s %-8s %-8s %-8s\n", "TIME", "PID", "SIZE", "RSSANON", "RSSFILE", "RSSSHMEM"); - } - } - else if (env.sysstat) - { - rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), handle_event_sysstat, NULL, NULL); - if (!rb) - { - err = -1; - fprintf(stderr, "Failed to create ring buffer\n"); - goto cleanup; - } - } - - while (!exiting) - { - if (env.paf) - { - err = ring_buffer__poll(rb, 1000 /* timeout, ms */); - /* Ctrl-C will cause -EINTR */ - if (err == -EINTR) - { - err = 0; - break; - } - if (err < 0) - { - printf("Error polling perf buffer: %d\n", err); - break; - } - } - else if (env.pr) - { - err = ring_buffer__poll(rb, 100 /* timeout, ms */); - /* Ctrl-C will cause -EINTR */ - if (err == -EINTR) - { - err = 0; - break; - } - if (err < 0) - { - printf("Error polling perf buffer: %d\n", err); - break; - } - } - else if (env.procstat) - { - err = ring_buffer__poll(rb, 100 /* timeout, ms */); - /* Ctrl-C will cause -EINTR */ - if (err == -EINTR) - { - err = 0; - break; - } - if (err < 0) - { - printf("Error polling perf buffer: %d\n", err); - break; - } - } - else if (env.sysstat) - { - err = ring_buffer__poll(rb, 100 /* timeout, ms */); - /* Ctrl-C will cause -EINTR */ - if (err == -EINTR) - { - err = 0; - break; - } - if (err < 0) - { - printf("Error polling perf buffer: %d\n", err); - break; - } - } - else - { - printf("请输入要使用的功能...\n"); - break; - } - } - -cleanup: - /* Clean up */ - ring_buffer__free(rb); - mem_watcher_bpf__destroy(skel); - return err < 0 ? -err : 0; -} \ No newline at end of file diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/paf.bpf.c b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/paf.bpf.c index bb8538e3b..8fefcf67c 100644 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/paf.bpf.c +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/paf.bpf.c @@ -10,7 +10,7 @@ #include #include #include -#include "paf.h" +#include "mem_watcher.h" char LICENSE[] SEC("license") = "Dual BSD/GPL"; diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/paf.c b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/paf.c index e1460ef99..3057fae61 100644 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/paf.c +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/paf.c @@ -11,216 +11,6 @@ #include #include -static struct env -{ - long choose_pid; - long time_s; - long rss; -} env; -/* -const char *argp_program_version = "bootstrap 0.0"; -const char *argp_program_bug_address = ""; - -const char argp_program_doc[] = -"BPF bootstrap demo application.\n" -"\n" -"It traces process start and exits and shows associated \n" -"information (filename, process duration, PID and PPID, etc).\n" -"\n" -"USAGE: ./bootstrap [-d ] [-v]\n"; -*/ -static const struct argp_option opts[] = { - {"choose_pid", 'p', "PID", 0, "选择进程号打印。"}, - {"time_s", 't', "MS", 0, "延时打印。单位:毫秒"}, - {"Rss", 'r', NULL, 0, "进程页面。"}, -}; - -pid_t own_pid; - -static error_t parse_arg(int key, char *arg, struct argp_state *state) -{ - switch (key) - { - case 'p': - env.choose_pid = strtol(arg, NULL, 10); - break; - case 't': - env.time_s = strtol(arg, NULL, 10); - break; - case 'r': - env.rss = true; - break; - case ARGP_KEY_ARG: - argp_usage(state); - break; - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -static const struct argp argp = { - .options = opts, - .parser = parse_arg, - // .doc = argp_program_doc, -}; - -static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) -{ - return vfprintf(stderr, format, args); -} - -static volatile bool exiting; - -static void sig_handler(int sig) -{ - exiting = true; -} - -static void msleep(long secs) -{ - struct timeval tval; - - tval.tv_sec = secs / 1000; - tval.tv_usec = (secs * 1000) % 1000000; - select(0, NULL, NULL, NULL, &tval); -} -/* -static char* flags(int flag) -{ - if(flag & GFP_ATOMIC) - return "GFP_ATOMIC"; - if(flag & GFP_KERNEL) - return "GFP_KERNEL"; - if(flag & GFP_KERNEL_ACCOUNT) - return "GFP_KERNEL_ACCOUNT"; - if(flag & GFP_NOWAIT) - return "GFP_NOWAIT"; - if(flag & GFP_NOIO ) - return "GFP_NOIO "; - if(flag & GFP_NOFS) - return "GFP_NOFS"; - if(flag & GFP_USER) - return "GFP_USER"; - if(flag & GFP_DMA) - return "GFP_DMA"; - if(flag & GFP_DMA32) - return "GFP_DMA32"; - if(flag & GFP_HIGHUSER) - return "GFP_HIGHUSER"; - if(flag & GFP_HIGHUSER_MOVABLE) - return "GFP_HIGHUSER_MOVABLE"; - if(flag & GFP_TRANSHUGE_LIGHT) - return "GFP_TRANSHUGE_LIGHT"; - return; -} -*/ -static int handle_event(void *ctx, void *data, size_t data_sz) -{ - const struct event *e = data; - struct tm *tm; - char ts[32]; - time_t t; - - time(&t); - tm = localtime(&t); - strftime(ts, sizeof(ts), "%H:%M:%S", tm); - - printf("%-8lu %-8lu %-8lu %-8lu %-8x\n", - e->min, e->low, e->high, e->present, e->flag); - /* 睡眠会导致程序无法终止,所以需要注释掉这个代码块 */ - // if(env.time_s != 0) { - // msleep(env.time_s); - // } - // else { - // msleep(1000); - // } - return 0; -} - -int main(int argc, char **argv) -{ - struct ring_buffer *rb = NULL; - struct paf_bpf *skel; - int err; - - err = argp_parse(&argp, argc, argv, 0, NULL, NULL); - if (err) - return err; - own_pid = getpid(); - - libbpf_set_strict_mode(LIBBPF_STRICT_ALL); - /* Set up libbpf errors and debug info callback */ - libbpf_set_print(libbpf_print_fn); - - /* Cleaner handling of Ctrl-C */ - signal(SIGINT, sig_handler); - signal(SIGTERM, sig_handler); - - /* Load and verify BPF application */ - skel = paf_bpf__open(); - if (!skel) - { - fprintf(stderr, "Failed to open and load BPF skeleton\n"); - return 1; - } - - skel->bss->user_pid = own_pid; - - /* Load & verify BPF programs */ - err = paf_bpf__load(skel); - if (err) - { - fprintf(stderr, "Failed to load and verify BPF skeleton\n"); - goto cleanup; - } - - /* Attach tracepoints */ - err = paf_bpf__attach(skel); - if (err) - { - fprintf(stderr, "Failed to attach BPF skeleton\n"); - goto cleanup; - } - - /* Set up ring buffer polling */ - rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), handle_event, NULL, NULL); - if (!rb) - { - err = -1; - fprintf(stderr, "Failed to create ring buffer\n"); - goto cleanup; - } - - /* Process events */ - if (env.rss == true) - { - printf("%-8s %-8s %-8s %-8s %-8s %-8s %-8s\n", "TIME", "PID", "VMSIZE", "VMDATA", "VMSTK", "VMPTE", "VMSWAP"); - } - else - { - printf("%-8s %-8s %-8s %-8s %-8s %-8s\n", "TIME", "PID", "SIZE", "RSSANON", "RSSFILE", "RSSSHMEM"); - } - - while (!exiting) - { - err = ring_buffer__poll(rb, 100 /* timeout, ms */); - /* Ctrl-C will cause -EINTR */ - if (err == -EINTR) - { - err = 0; - break; - } - if (err < 0) - { - printf("Error polling perf buffer: %d\n", err); - break; - } - } - -cleanup: - /* Clean up */ - ring_buffer__free(rb); - paf_bpf__destroy(skel); - return err < 0 ? -err : 0; +int main(int argc, char **argv) { + } diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/paf.h b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/paf.h deleted file mode 100644 index 25aaf6b53..000000000 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/paf.h +++ /dev/null @@ -1,59 +0,0 @@ -/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ -/* Copyright (c) 2020 Facebook */ -#ifndef __PAF_H -#define __PAF_H - -#define TASK_COMM_LEN 16 -#define MAX_FILENAME_LEN 127 - -#define ___GFP_DMA 0x01u -#define ___GFP_HIGHMEM 0x02u -#define ___GFP_DMA32 0x04u -#define ___GFP_MOVABLE 0x08u -#define ___GFP_RECLAIMABLE 0x10u -#define ___GFP_HIGH 0x20u -#define ___GFP_IO 0x40u -#define ___GFP_FS 0x80u -#define ___GFP_WRITE 0x100u -#define ___GFP_NOWARN 0x200u -#define ___GFP_RETRY_MAYFAIL 0x400u -#define ___GFP_NOFAIL 0x800u -#define ___GFP_NORETRY 0x1000u -#define ___GFP_MEMALLOC 0x2000u -#define ___GFP_COMP 0x4000u -#define ___GFP_ZERO 0x8000u -#define ___GFP_NOMEMALLOC 0x10000u -#define ___GFP_HARDWALL 0x20000u -#define ___GFP_THISNODE 0x40000u -#define ___GFP_ATOMIC 0x80000u -#define ___GFP_ACCOUNT 0x100000u -#define ___GFP_DIRECT_RECLAIM 0x200000u -#define ___GFP_KSWAPD_RECLAIM 0x400000u - -#define GFP_ATOMIC (__GFP_HIGH|__GFP_ATOMIC|__GFP_KSWAPD_RECLAIM) -#define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS) -#define GFP_KERNEL_ACCOUNT (GFP_KERNEL | __GFP_ACCOUNT) -#define GFP_NOWAIT (__GFP_KSWAPD_RECLAIM) -#define GFP_NOIO (__GFP_RECLAIM) -#define GFP_NOFS (__GFP_RECLAIM | __GFP_IO) -#define GFP_USER (__GFP_RECLAIM | __GFP_IO | __GFP_FS | __GFP_HARDWALL) -#define GFP_DMA __GFP_DMA -#define GFP_DMA32 __GFP_DMA32 -#define GFP_HIGHUSER (GFP_USER | __GFP_HIGHMEM) -#define GFP_HIGHUSER_MOVABLE (GFP_HIGHUSER | __GFP_MOVABLE) -#define GFP_TRANSHUGE_LIGHT ((GFP_HIGHUSER_MOVABLE | __GFP_COMP | \ - __GFP_NOMEMALLOC | __GFP_NOWARN) & ~__GFP_RECLAIM) -#define GFP_TRANSHUGE (GFP_TRANSHUGE_LIGHT | __GFP_DIRECT_RECLAIM) - -struct paf_event { - unsigned long min; - unsigned long low; - unsigned long high; - unsigned long present; - unsigned long protection; - int flag; -}; - - - -#endif /* __PAF_H */ diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/pr.bpf.c b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/pr.bpf.c index 38112b1ca..cd0834399 100644 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/pr.bpf.c +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/pr.bpf.c @@ -11,7 +11,7 @@ #include #include #include -#include "pr.h" +#include "mem_watcher.h" char LICENSE[] SEC("license") = "Dual BSD/GPL"; diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/pr.c b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/pr.c index 1b6f93eb0..c4dcd6f3f 100644 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/pr.c +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/pr.c @@ -11,184 +11,6 @@ #include #include -#define GFP_ATOMIC 0x -static struct env -{ - long choose_pid; - long time_s; - long rss; -} env; -/* -const char *argp_program_version = "bootstrap 0.0"; -const char *argp_program_bug_address = ""; +int main(int argc, char **argv){ -const char argp_program_doc[] = -"BPF bootstrap demo application.\n" -"\n" -"It traces process start and exits and shows associated \n" -"information (filename, process duration, PID and PPID, etc).\n" -"\n" -"USAGE: ./bootstrap [-d ] [-v]\n"; -*/ -static const struct argp_option opts[] = { - {"choose_pid", 'p', "PID", 0, "选择进程号打印。"}, - {"time_s", 't', "MS", 0, "延时打印。单位:毫秒"}, - {"Rss", 'r', NULL, 0, "进程页面。"}, -}; - -pid_t own_pid; - -static error_t parse_arg(int key, char *arg, struct argp_state *state) -{ - switch (key) - { - case 'p': - env.choose_pid = strtol(arg, NULL, 10); - break; - case 't': - env.time_s = strtol(arg, NULL, 10); - break; - case 'r': - env.rss = true; - break; - case ARGP_KEY_ARG: - argp_usage(state); - break; - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -static const struct argp argp = { - .options = opts, - .parser = parse_arg, - // .doc = argp_program_doc, -}; - -static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) -{ - return vfprintf(stderr, format, args); -} - -static volatile bool exiting; - -static void sig_handler(int sig) -{ - exiting = true; -} - -static void msleep(long secs) -{ - struct timeval tval; - - tval.tv_sec = secs / 1000; - tval.tv_usec = (secs * 1000) % 1000000; - select(0, NULL, NULL, NULL, &tval); -} - -static int handle_event(void *ctx, void *data, size_t data_sz) -{ - const struct event *e = data; - struct tm *tm; - char ts[32]; - time_t t; - - time(&t); - tm = localtime(&t); - strftime(ts, sizeof(ts), "%H:%M:%S", tm); - - printf("%-8lu %-8lu %-8u %-8u %-8u\n", - e->reclaim, e->reclaimed, e->unqueued_dirty, e->congested, e->writeback); - /* 睡眠会导致程序无法终止,所以需要注释掉这个代码块 */ - // if (env.time_s != 0) - // { - // msleep(env.time_s); - // } - // else - // { - // msleep(1000); - // } - return 0; -} - -int main(int argc, char **argv) -{ - struct ring_buffer *rb = NULL; - struct pr_bpf *skel; - int err; - - err = argp_parse(&argp, argc, argv, 0, NULL, NULL); - if (err) - return err; - - own_pid = getpid(); - - libbpf_set_strict_mode(LIBBPF_STRICT_ALL); - /* Set up libbpf errors and debug info callback */ - libbpf_set_print(libbpf_print_fn); - - /* Cleaner handling of Ctrl-C */ - signal(SIGINT, sig_handler); - signal(SIGTERM, sig_handler); - - /* Load and verify BPF application */ - skel = pr_bpf__open(); - if (!skel) - { - fprintf(stderr, "Failed to open and load BPF skeleton\n"); - return 1; - } - - skel->bss->user_pid = own_pid; - - /* Load & verify BPF programs */ - err = pr_bpf__load(skel); - if (err) - { - fprintf(stderr, "Failed to load and verify BPF skeleton\n"); - goto cleanup; - } - - /* Attach tracepoints */ - err = pr_bpf__attach(skel); - if (err) - { - fprintf(stderr, "Failed to attach BPF skeleton\n"); - goto cleanup; - } - - /* Set up ring buffer polling */ - rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), handle_event, NULL, NULL); - if (!rb) - { - err = -1; - fprintf(stderr, "Failed to create ring buffer\n"); - goto cleanup; - } - - /* Process events */ - printf("%-8s %-8s %-8s %-8s %-8s\n", "RECLAIM", "RECLAIMED", "UNQUEUE", "CONGESTED", "WRITEBACK"); - - while (!exiting) - { - err = ring_buffer__poll(rb, 100 /* timeout, ms */); - /* Ctrl-C will cause -EINTR */ - if (err == -EINTR) - { - err = 0; - break; - } - if (err < 0) - { - printf("Error polling perf buffer: %d\n", err); - break; - } - } - -cleanup: - /* Clean up */ - ring_buffer__free(rb); - pr_bpf__destroy(skel); - return err < 0 ? -err : 0; } diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/pr.h b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/pr.h deleted file mode 100644 index 67f166bd3..000000000 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/pr.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ -/* Copyright (c) 2020 Facebook */ -#ifndef __BOOTSTRAP_H -#define __BOOTSTRAP_H - - -struct pr_event { - unsigned long reclaim; - unsigned long reclaimed; - unsigned int unqueued_dirty; - unsigned int congested; - unsigned int writeback; -}; - - - -#endif /* __BOOTSTRAP_H */ diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/procstat.bpf.c b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/procstat.bpf.c index 2f74ea5bd..6d44f33ac 100644 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/procstat.bpf.c +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/procstat.bpf.c @@ -11,7 +11,7 @@ #include #include #include -#include "procstat.h" +#include "mem_watcher.h" char LICENSE[] SEC("license") = "Dual BSD/GPL"; diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/procstat.c b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/procstat.c index 92a15b525..90876c125 100644 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/procstat.c +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/procstat.c @@ -6,211 +6,11 @@ #include #include #include -#include "procstat.h" +#include "mem_watcher.h" #include "procstat.skel.h" #include #include -static struct env -{ - long choose_pid; - long time_s; - long rss; -} env; -/* -const char *argp_program_version = "bootstrap 0.0"; -const char *argp_program_bug_address = ""; - -const char argp_program_doc[] = -"BPF bootstrap demo application.\n" -"\n" -"It traces process start and exits and shows associated \n" -"information (filename, process duration, PID and PPID, etc).\n" -"\n" -"USAGE: ./bootstrap [-d ] [-v]\n"; -*/ -static const struct argp_option opts[] = { - {"choose_pid", 'p', "PID", 0, "选择进程号打印。"}, - {"time_s", 't', "MS", 0, "延时打印。单位:毫秒"}, - {"Rss", 'r', NULL, 0, "进程页面。"}, -}; - -pid_t own_pid; - -static error_t parse_arg(int key, char *arg, struct argp_state *state) -{ - switch (key) - { - case 'p': - env.choose_pid = strtol(arg, NULL, 10); - break; - case 't': - env.time_s = strtol(arg, NULL, 10); - break; - case 'r': - env.rss = true; - break; - case ARGP_KEY_ARG: - argp_usage(state); - break; - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -static const struct argp argp = { - .options = opts, - .parser = parse_arg, - // .doc = argp_program_doc, -}; - -static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) -{ - return vfprintf(stderr, format, args); -} - -static volatile bool exiting; - -static void sig_handler(int sig) -{ - exiting = true; -} - -static void msleep(long secs) -{ - struct timeval tval; - - tval.tv_sec = secs / 1000; - tval.tv_usec = (secs * 1000) % 1000000; - select(0, NULL, NULL, NULL, &tval); -} - -static int handle_event(void *ctx, void *data, size_t data_sz) -{ - const struct procstat_event *e = data; - struct tm *tm; - char ts[32]; - time_t t; - - time(&t); - tm = localtime(&t); - strftime(ts, sizeof(ts), "%H:%M:%S", tm); - - if (env.choose_pid) - { - if (e->pid == env.choose_pid) - { - if (env.rss == true) - printf("%-8s %-8d %-8ld %-8ld %-8ld %-8lld %-8lld\n", ts, e->pid, e->vsize, e->Vdata, e->Vstk, e->VPTE, e->vswap); - else - printf("%-8s %-8d %-8ld %-8lld %-8lld %-8lld\n", ts, e->pid, e->size, e->rssanon, e->rssfile, e->rssshmem); - } - } - else - { - if (env.rss == true) - printf("%-8s %-8d %-8ld %-8ld %-8ld %-8lld %-8lld\n", ts, e->pid, e->vsize, e->Vdata, e->Vstk, e->VPTE, e->vswap); - else - printf("%-8s %-8d %-8ld %-8lld %-8lld %-8lld\n", ts, e->pid, e->size, e->rssanon, e->rssfile, e->rssshmem); - } - /* 睡眠会导致程序无法终止,所以需要注释掉这个代码块 */ - // if (env.time_s != NULL) - // { - // msleep(env.time_s); - // } - // else - // { - // msleep(1000); - // } - return 0; -} - -int main(int argc, char **argv) -{ - struct ring_buffer *rb = NULL; - struct procstat_bpf *skel; - int err; - - err = argp_parse(&argp, argc, argv, 0, NULL, NULL); - if (err) - return err; - - own_pid = getpid(); - - libbpf_set_strict_mode(LIBBPF_STRICT_ALL); - /* Set up libbpf errors and debug info callback */ - libbpf_set_print(libbpf_print_fn); - - /* Cleaner handling of Ctrl-C */ - signal(SIGINT, sig_handler); - signal(SIGTERM, sig_handler); - - /* Load and verify BPF application */ - skel = procstat_bpf__open(); - if (!skel) - { - fprintf(stderr, "Failed to open and load BPF skeleton\n"); - return 1; - } - - skel->bss->user_pid = own_pid; +int main(int argc, char **argv) { - /* Load & verify BPF programs */ - err = procstat_bpf__load(skel); - if (err) - { - fprintf(stderr, "Failed to load and verify BPF skeleton\n"); - goto cleanup; - } - - /* Attach tracepoints */ - err = procstat_bpf__attach(skel); - if (err) - { - fprintf(stderr, "Failed to attach BPF skeleton\n"); - goto cleanup; - } - - /* Set up ring buffer polling */ - rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), handle_event, NULL, NULL); - if (!rb) - { - err = -1; - fprintf(stderr, "Failed to create ring buffer\n"); - goto cleanup; - } - - /* Process events */ - if (env.rss == true) - { - printf("%-8s %-8s %-8s %-8s %-8s %-8s %-8s\n", "TIME", "PID", "VMSIZE", "VMDATA", "VMSTK", "VMPTE", "VMSWAP"); - } - else - { - printf("%-8s %-8s %-8s %-8s %-8s %-8s\n", "TIME", "PID", "SIZE", "RSSANON", "RSSFILE", "RSSSHMEM"); - } - - while (!exiting) - { - err = ring_buffer__poll(rb, 100 /* timeout, ms */); - /* Ctrl-C will cause -EINTR */ - if (err == -EINTR) - { - err = 0; - break; - } - if (err < 0) - { - printf("Error polling perf buffer: %d\n", err); - break; - } - } - -cleanup: - /* Clean up */ - ring_buffer__free(rb); - procstat_bpf__destroy(skel); - - return err < 0 ? -err : 0; -} +} \ No newline at end of file diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/procstat.h b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/procstat.h deleted file mode 100644 index 0da40b028..000000000 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/procstat.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ -/* Copyright (c) 2020 Facebook */ -#ifndef __PROCSTAT_H -#define __PROCSTAT_H - -#define TASK_COMM_LEN 16 -#define MAX_FILENAME_LEN 127 - -struct procstat_event { -/*进程内存状态报告*/ - pid_t pid; - long nvcsw; - long nivcsw; - long vsize; //虚拟内存 - long size; //物理内存 - long long rssanon; //匿名页面 - long long rssfile; //文件页面 - long long rssshmem; //共享页面 - long long vswap; //交换页面 - long long Hpages; //hugetlbPages - long Vdata; //Private data segments - long Vstk; //User stack - long long VPTE; -}; - - - -#endif /* __PROCSTAT_H */ diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/sysstat.bpf.c b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/sysstat.bpf.c index 69ba5e04e..748997605 100644 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/sysstat.bpf.c +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/sysstat.bpf.c @@ -11,7 +11,7 @@ #include #include #include -#include "sysstat.h" +#include "mem_watcher.h" char LICENSE[] SEC("license") = "Dual BSD/GPL"; diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/sysstat.c b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/sysstat.c index 17a32008f..448210d90 100644 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/sysstat.c +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/sysstat.c @@ -4,184 +4,11 @@ #include #include #include -#include "sysstat.h" +#include "mem_watcher.h" #include "sysstat.skel.h" #include #include -static struct env -{ - long choose_pid; - long time_s; - long rss; -} env; - -static const struct argp_option opts[] = { - {"choose_pid", 'p', "PID", 0, "选择进程号打印。"}, - {"time_s", 't', "MS", 0, "延时打印。单位:毫秒"}, - {"Rss", 'r', NULL, 0, "进程页面。"}, -}; - -static error_t parse_arg(int key, char *arg, struct argp_state *state) -{ - switch (key) - { - case 'p': - env.choose_pid = strtol(arg, NULL, 10); - break; - case 't': - env.time_s = strtol(arg, NULL, 10); - break; - case 'r': - env.rss = true; - break; - case ARGP_KEY_ARG: - argp_usage(state); - break; - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -static const struct argp argp = { - .options = opts, - .parser = parse_arg, - // .doc = argp_program_doc, -}; - -static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) -{ - return vfprintf(stderr, format, args); -} - -static volatile bool exiting; - -static void sig_handler(int sig) -{ - exiting = true; -} - -static void msleep(long secs) -{ - struct timeval tval; - - tval.tv_sec = secs / 1000; - tval.tv_usec = (secs * 1000) % 1000000; - select(0, NULL, NULL, NULL, &tval); -} - -static int handle_event(void *ctx, void *data, size_t data_sz) -{ - const struct sysstat_event *e = data; - struct tm *tm; - char ts[32]; - time_t t; - - time(&t); - tm = localtime(&t); - strftime(ts, sizeof(ts), "%H:%M:%S", tm); - - printf("%-8lu %-8lu %-8lu %-8lu %-8lu %-8lu %-8lu----- %-8lu %-8lu %-8lu %-8lu %-8lu----- %-8lu %-8lu %-8lu %-8lu--- %-8lu %-8lu %-8lu %-8lu %-8lu\n", - e->anon_active + e->file_active, e->file_inactive + e->anon_inactive, e->anon_active, e->anon_inactive, e->file_active, e->file_inactive, e->unevictable, e->file_dirty, e->writeback, e->anon_mapped, e->file_mapped, e->shmem, e->slab_reclaimable + e->kernel_misc_reclaimable, e->slab_reclaimable + e->slab_unreclaimable, e->slab_reclaimable, e->slab_unreclaimable, e->unstable_nfs, e->writeback_temp, e->anon_thps, e->shmem_thps, e->pmdmapped); - /* 睡眠会导致程序无法终止,所以需要注释掉这个代码块 */ - // if (env.time_s != 0) - // { - // msleep(env.time_s); - // } - // else - // { - // msleep(1000); - // } - return 0; -} - -pid_t own_pid; - -int main(int argc, char **argv) -{ - struct ring_buffer *rb = NULL; - struct sysstat_bpf *skel; - int err; - - err = argp_parse(&argp, argc, argv, 0, NULL, NULL); - if (err) - return err; - - own_pid = getpid(); - - libbpf_set_strict_mode(LIBBPF_STRICT_ALL); - /* Set up libbpf errors and debug info callback */ - libbpf_set_print(libbpf_print_fn); - - /* Cleaner handling of Ctrl-C */ - signal(SIGINT, sig_handler); - signal(SIGTERM, sig_handler); - - /* Load and verify BPF application */ - skel = sysstat_bpf__open(); - if (!skel) - { - fprintf(stderr, "Failed to open and load BPF skeleton\n"); - return 1; - } - - skel->bss->user_pid = own_pid; - - /* Load & verify BPF programs */ - err = sysstat_bpf__load(skel); - if (err) - { - fprintf(stderr, "Failed to load and verify BPF skeleton\n"); - goto cleanup; - } - - /* Attach tracepoints */ - err = sysstat_bpf__attach(skel); - if (err) - { - fprintf(stderr, "Failed to attach BPF skeleton\n"); - goto cleanup; - } - - /* Set up ring buffer polling */ - rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), handle_event, NULL, NULL); - if (!rb) - { - err = -1; - fprintf(stderr, "Failed to create ring buffer\n"); - goto cleanup; - } - - /* Process events */ - if (env.rss == true) - { - printf("%-8s %-8s %-8s %-8s %-8s %-8s %-8s\n", "TIME", "PID", "VMSIZE", "VMDATA", "VMSTK", "VMPTE", "VMSWAP"); - } - else - { - printf("%-8s %-8s %-8s %-8s %-8s %-8s\n", "TIME", "PID", "SIZE", "RSSANON", "RSSFILE", "RSSSHMEM"); - } - - while (!exiting) - { - err = ring_buffer__poll(rb, 100 /* timeout, ms */); - /* Ctrl-C will cause -EINTR */ - if (err == -EINTR) - { - err = 0; - break; - } - if (err < 0) - { - printf("Error polling perf buffer: %d\n", err); - break; - } - } - -cleanup: - /* Clean up */ - ring_buffer__free(rb); - sysstat_bpf__destroy(skel); - return err < 0 ? -err : 0; -} +int main(int argc, char **argv) { + +} \ No newline at end of file diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/sysstat.h b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/sysstat.h deleted file mode 100644 index ba131007f..000000000 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/sysstat.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef __SYSSTAT_H -#define __SYSSTAT_H - -#define TASK_COMM_LEN 16 -#define MAX_FILENAME_LEN 127 - -struct sysstat_event -{ - /*系统内存状态报告*/ - unsigned long present; - unsigned long anon_inactive; // 0 - unsigned long anon_active; // 1 - unsigned long file_inactive; // 2 - unsigned long file_active; // 3 - unsigned long unevictable; // 不可回收页面 - unsigned long slab_reclaimable; - unsigned long slab_unreclaimable; - unsigned long anon_isolated; // 匿名隔离页面 - unsigned long file_isolated; // 文件隔离页面 - - unsigned long working_nodes; // 12 - unsigned long working_refault; - unsigned long working_activate; - unsigned long working_restore; - unsigned long working_nodereclaim; - - unsigned long anon_mapped; // 17 - unsigned long file_mapped; - - unsigned long file_pages; // 19 - unsigned long file_dirty; - unsigned long writeback; - unsigned long writeback_temp; - - unsigned long shmem; // 共享内存23 - unsigned long shmem_thps; - unsigned long pmdmapped; - unsigned long anon_thps; - unsigned long unstable_nfs; - unsigned long vmscan_write; - unsigned long vmscan_immediate; - - unsigned long diried; - unsigned long written; - unsigned long kernel_misc_reclaimable; -}; - -#endif /* __SYSSTAT_H */ From 48f3f67ba0cb9db3d5737d8d2aba22c51a5a6b5a Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Sat, 16 Mar 2024 02:12:15 +0000 Subject: [PATCH 11/55] adapt to MagicEyes Signed-off-by: LiuLingze --- .../stack_analyzer/CMakeLists.txt | 6 +- .../bpf/{io_count.bpf.c => io.bpf.c} | 2 +- .../bpf/{mem_count.bpf.c => mem.bpf.c} | 0 .../{off_cpu_count.bpf.c => off_cpu.bpf.c} | 0 .../bpf/{on_cpu_count.bpf.c => on_cpu.bpf.c} | 0 .../stack_analyzer/bpf/pre_count.bpf.c | 132 --- .../bpf/{stack_count.bpf.c => probe.bpf.c} | 0 .../stack_analyzer/bpf/readahead.bpf.c | 131 +++ .../stack_analyzer/bpf/template.bpf.c | 14 + .../include/bpf/eBPFStackCollector.h | 125 +++ .../stack_analyzer/include/bpf/io.h | 41 + .../stack_analyzer/include/bpf/mem.h | 90 ++ .../stack_analyzer/include/bpf/off_cpu.h | 23 + .../stack_analyzer/include/bpf/on_cpu.h | 32 + .../stack_analyzer/include/bpf/probe.h | 22 + .../stack_analyzer/include/bpf/readahead.h | 32 + .../stack_analyzer/include/bpf/template.h | 31 + .../include/{elf.h => dt_elf.h} | 2 +- .../include/{symbol.h => dt_symbol.h} | 0 .../stack_analyzer/include/sa_user.h | 138 --- .../src/bpf/eBPFStackCollector.cpp | 218 ++++ .../stack_analyzer/src/bpf/io.cpp | 55 ++ .../stack_analyzer/src/bpf/mem.cpp | 66 ++ .../stack_analyzer/src/bpf/off_cpu.cpp | 33 + .../stack_analyzer/src/bpf/on_cpu.cpp | 124 +++ .../stack_analyzer/src/bpf/probe.cpp | 44 + .../stack_analyzer/src/bpf/readahead.cpp | 39 + .../stack_analyzer/src/bpf/template.cpp | 26 + .../stack_analyzer/src/{elf.cc => dt_elf.cpp} | 8 +- .../src/{symbol.cc => dt_symbol.cpp} | 4 +- .../stack_analyzer/src/main.cpp | 200 ++++ .../stack_analyzer/src/stack_analyzer.cc | 934 ------------------ 32 files changed, 1356 insertions(+), 1216 deletions(-) rename MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/{io_count.bpf.c => io.bpf.c} (99%) rename MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/{mem_count.bpf.c => mem.bpf.c} (100%) rename MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/{off_cpu_count.bpf.c => off_cpu.bpf.c} (100%) rename MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/{on_cpu_count.bpf.c => on_cpu.bpf.c} (100%) delete mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/pre_count.bpf.c rename MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/{stack_count.bpf.c => probe.bpf.c} (100%) create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/readahead.bpf.c create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/template.bpf.c create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/eBPFStackCollector.h create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/io.h create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/mem.h create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/off_cpu.h create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/on_cpu.h create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/probe.h create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/readahead.h create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/template.h rename MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/{elf.h => dt_elf.h} (96%) rename MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/{symbol.h => dt_symbol.h} (100%) create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/eBPFStackCollector.cpp create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/io.cpp create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/mem.cpp create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/off_cpu.cpp create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/on_cpu.cpp create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/probe.cpp create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/readahead.cpp create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/template.cpp rename MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/{elf.cc => dt_elf.cpp} (98%) rename MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/{symbol.cc => dt_symbol.cpp} (99%) create mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/main.cpp delete mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/stack_analyzer.cc diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/CMakeLists.txt b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/CMakeLists.txt index df6f7192b..ebe631dab 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/CMakeLists.txt +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/CMakeLists.txt @@ -13,7 +13,8 @@ set(TOOL_NAME stack_analyzer) set(TOOL_BELONG_TO_MODULE system_diagnosis) -file(GLOB STACK_ANALYZER_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cc) +file(GLOB STACK_ANALYZER_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +file(GLOB STACK_ANALYZER_WAPPER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/bpf/*.cpp) file(GLOB apps ${CMAKE_CURRENT_SOURCE_DIR}/bpf/*.bpf.c) # 若不用Rust,则排除 profile.bpf.c @@ -28,6 +29,7 @@ if (NOT EXISTS ${SRC_GEN_TARGET_DIR}) message(STATUS "directory create success") endif () +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/ ${SRC_GEN_TARGET_DIR}) # 遍历文件夹内所有的bpf.c foreach(app ${apps}) get_filename_component(app_stem ${app} NAME_WE) @@ -36,7 +38,7 @@ foreach(app ${apps}) add_dependencies(${app_stem}_skel libbpf-build bpftool-build) endforeach() -add_executable(${TOOL_NAME} ${STACK_ANALYZER_SOURCE_FILES}) +add_executable(${TOOL_NAME} ${STACK_ANALYZER_WAPPER_FILES} ${STACK_ANALYZER_SOURCE_FILES}) foreach (app ${apps}) get_filename_component(app_stem ${app} NAME_WE) target_link_libraries(${TOOL_NAME} ${app_stem}_skel -lstdc++) diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/io_count.bpf.c b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/io.bpf.c similarity index 99% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/io_count.bpf.c rename to MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/io.bpf.c index fa6d1ccb4..51aa98d47 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/io_count.bpf.c +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/io.bpf.c @@ -22,7 +22,7 @@ #include #include "sa_ebpf.h" -#include "bpf/IOStackCollector.h" +#include "bpf/io.h" #include "task.h" DeclareCommonMaps(io_tuple); diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/mem_count.bpf.c b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/mem.bpf.c similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/mem_count.bpf.c rename to MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/mem.bpf.c diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/off_cpu_count.bpf.c b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/off_cpu.bpf.c similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/off_cpu_count.bpf.c rename to MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/off_cpu.bpf.c diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/on_cpu_count.bpf.c b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/on_cpu.bpf.c similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/on_cpu_count.bpf.c rename to MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/on_cpu.bpf.c diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/pre_count.bpf.c b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/pre_count.bpf.c deleted file mode 100644 index c2da7829c..000000000 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/pre_count.bpf.c +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright 2023 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 内核态bpf的预读取分析模块代码 - -#include "vmlinux.h" -#include -#include -#include - -#include "sa_ebpf.h" -#include "task.h" - -#define MINBLOCK_US 1ULL -#define MAXBLOCK_US 99999999ULL - -DeclareCommonMaps(ra_tuple); -DeclareCommonVar(); - -int apid = 0; -BPF_HASH(in_ra, u32, psid); -BPF_HASH(page_psid, struct page *, psid); - -SEC("fentry/page_cache_ra_unbounded") //fentry在内核函数page_cache_ra_unbounded进入时触发的挂载点 -int BPF_PROG(page_cache_ra_unbounded) -{ - struct task_struct* curr = (struct task_struct*)bpf_get_current_task(); - ignoreKthread(curr); - u32 pid = get_task_ns_pid(curr); //获取当前进程tgid,用户空间的pid即是tgid - - if ((apid >= 0 && pid != apid) || !pid || pid == self_pid) - return 0; - - u32 tgid = get_task_ns_tgid(curr); - bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); //更新pid_tgid表中的pid对应的值 - comm *p = bpf_map_lookup_elem(&pid_comm, &pid); //p指向pid_comm表中pid对应的值 - if (!p) - { - comm name; - bpf_get_current_comm(&name, COMM_LEN); //获取当前进程名 - bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST); //在pid_comm表中更新pid对应的值 - } - - psid apsid = { - .pid = pid, - .usid = u ? USER_STACK : -1, - .ksid = k ? KERNEL_STACK : -1, - }; - - ra_tuple *d = bpf_map_lookup_elem(&psid_count, &apsid); //d指向psid_count表中的apsid对应的类型为tuple的值 - if (!d) - { - ra_tuple a = {.expect = 0, .truth = 0}; //初始化为0 - bpf_map_update_elem(&psid_count, &apsid, &a, BPF_ANY); //更新psid_count表中的apsid的值为a - } - bpf_map_update_elem(&in_ra, &pid, &apsid, BPF_ANY); //更新in_ra表中的pid对应的值为apsid - return 0; -} - - -SEC("fexit/alloc_pages") //fexit在内核函数alloc_pages退出时触发,挂载点为alloc_pages -int BPF_PROG(filemap_alloc_folio_ret, gfp_t gfp, unsigned int order, u64 ret) -{ - u32 pid = bpf_get_current_pid_tgid() >> 32; //pid为当前进程的pid - - if ((apid >= 0 && pid != apid) || !pid) - return 0; - - struct psid *apsid = bpf_map_lookup_elem(&in_ra, &pid); //apsid指向了当前in_ra中pid的表项内容 - if (!apsid) - return 0; - - ra_tuple *a = bpf_map_lookup_elem(&psid_count, apsid); //a是指向psid_count的apsid对应的内容 - if (!a) - return 0; - - const u32 lim = 1ul << order; //1 为长整型,左移order位,即2^order 即申请页的大小 - a->expect += lim; //a->expect+=页大小(未访问) - u64 addr; - bpf_core_read(&addr, sizeof(u64), &ret); //alloc_pages返回的值,即申请页的起始地址保存在addr中 - for (int i = 0; i < lim && i < 1024; i++, addr += 0x1000) - bpf_map_update_elem(&page_psid, &addr, apsid, BPF_ANY);//更新page_psid表中的addr(从页的起始地址开始到页的结束地址)所对应的值为apsid - - return 0; -} - -SEC("fexit/page_cache_ra_unbounded") -int BPF_PROG(page_cache_ra_unbounded_ret) //fexit在内核函数page_cache_ra_unbounded退出时触发的挂载点 -{ - u32 pid = bpf_get_current_pid_tgid() >> 32; //获取当前进程的pid - - if ((apid >= 0 && pid != apid) || !pid) - return 0; - - bpf_map_delete_elem(&in_ra, &pid); //删除了in_ra对应的pid的表项,即删除对应的栈计数信息 - return 0; -} - - -SEC("fentry/mark_page_accessed") //fentry在内核函数/mark_page_accessed进入时触发的挂载点,用于标记页面(page)已经被访问 -int BPF_PROG(mark_page_accessed, u64 page) -{ - u32 pid = bpf_get_current_pid_tgid() >> 32; //获取当前进程的pid - - if ((apid >= 0 && pid != apid) || !pid) - return 0; - psid *apsid; - apsid = bpf_map_lookup_elem(&page_psid, &page); //查看page_psid对应的 地址page 对应类型为psid的值,并保存在apsid - if (!apsid) - return 0; - ra_tuple *a = bpf_map_lookup_elem(&psid_count, apsid); //a指向psid_count的apsid的内容 - if (!a) - return 0; - a->truth++; //已访问 - bpf_map_delete_elem(&page_psid, &page); //删除page_psid的page对应的内容 - return 0; -} - -const char LICENSE[] SEC("license") = "GPL"; \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/stack_count.bpf.c b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/probe.bpf.c similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/stack_count.bpf.c rename to MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/probe.bpf.c diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/readahead.bpf.c b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/readahead.bpf.c new file mode 100644 index 000000000..6f20da8c9 --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/readahead.bpf.c @@ -0,0 +1,131 @@ +// Copyright 2023 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// 内核态bpf的预读取分析模块代码 + +#include "vmlinux.h" +#include +#include +#include + +#include "sa_ebpf.h" +#include "task.h" +#include "bpf/readahead.h" + +#define MINBLOCK_US 1ULL +#define MAXBLOCK_US 99999999ULL + +DeclareCommonMaps(ra_tuple); +DeclareCommonVar(); + +int apid = 0; +BPF_HASH(in_ra, u32, psid); +BPF_HASH(page_psid, struct page *, psid); + +SEC("fentry/page_cache_ra_unbounded") // fentry在内核函数page_cache_ra_unbounded进入时触发的挂载点 +int BPF_PROG(page_cache_ra_unbounded) +{ + struct task_struct *curr = (struct task_struct *)bpf_get_current_task(); + ignoreKthread(curr); + u32 pid = get_task_ns_pid(curr); // 获取当前进程tgid,用户空间的pid即是tgid + + if ((apid >= 0 && pid != apid) || !pid || pid == self_pid) + return 0; + + u32 tgid = get_task_ns_tgid(curr); + bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); // 更新pid_tgid表中的pid对应的值 + comm *p = bpf_map_lookup_elem(&pid_comm, &pid); // p指向pid_comm表中pid对应的值 + if (!p) + { + comm name; + bpf_get_current_comm(&name, COMM_LEN); // 获取当前进程名 + bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST); // 在pid_comm表中更新pid对应的值 + } + + psid apsid = { + .pid = pid, + .usid = u ? USER_STACK : -1, + .ksid = k ? KERNEL_STACK : -1, + }; + + ra_tuple *d = bpf_map_lookup_elem(&psid_count, &apsid); // d指向psid_count表中的apsid对应的类型为tuple的值 + if (!d) + { + ra_tuple a = {.expect = 0, .truth = 0}; // 初始化为0 + bpf_map_update_elem(&psid_count, &apsid, &a, BPF_ANY); // 更新psid_count表中的apsid的值为a + } + bpf_map_update_elem(&in_ra, &pid, &apsid, BPF_ANY); // 更新in_ra表中的pid对应的值为apsid + return 0; +} + +SEC("fexit/alloc_pages") // fexit在内核函数alloc_pages退出时触发,挂载点为alloc_pages +int BPF_PROG(filemap_alloc_folio_ret, gfp_t gfp, unsigned int order, u64 ret) +{ + u32 pid = bpf_get_current_pid_tgid() >> 32; // pid为当前进程的pid + + if ((apid >= 0 && pid != apid) || !pid) + return 0; + + struct psid *apsid = bpf_map_lookup_elem(&in_ra, &pid); // apsid指向了当前in_ra中pid的表项内容 + if (!apsid) + return 0; + + ra_tuple *a = bpf_map_lookup_elem(&psid_count, apsid); // a是指向psid_count的apsid对应的内容 + if (!a) + return 0; + + const u32 lim = 1ul << order; // 1 为长整型,左移order位,即2^order 即申请页的大小 + a->expect += lim; // a->expect+=页大小(未访问) + u64 addr; + bpf_core_read(&addr, sizeof(u64), &ret); // alloc_pages返回的值,即申请页的起始地址保存在addr中 + for (int i = 0; i < lim && i < 1024; i++, addr += 0x1000) + bpf_map_update_elem(&page_psid, &addr, apsid, BPF_ANY); // 更新page_psid表中的addr(从页的起始地址开始到页的结束地址)所对应的值为apsid + + return 0; +} + +SEC("fexit/page_cache_ra_unbounded") +int BPF_PROG(page_cache_ra_unbounded_ret) // fexit在内核函数page_cache_ra_unbounded退出时触发的挂载点 +{ + u32 pid = bpf_get_current_pid_tgid() >> 32; // 获取当前进程的pid + + if ((apid >= 0 && pid != apid) || !pid) + return 0; + + bpf_map_delete_elem(&in_ra, &pid); // 删除了in_ra对应的pid的表项,即删除对应的栈计数信息 + return 0; +} + +SEC("fentry/mark_page_accessed") // fentry在内核函数/mark_page_accessed进入时触发的挂载点,用于标记页面(page)已经被访问 +int BPF_PROG(mark_page_accessed, u64 page) +{ + u32 pid = bpf_get_current_pid_tgid() >> 32; // 获取当前进程的pid + + if ((apid >= 0 && pid != apid) || !pid) + return 0; + psid *apsid; + apsid = bpf_map_lookup_elem(&page_psid, &page); // 查看page_psid对应的 地址page 对应类型为psid的值,并保存在apsid + if (!apsid) + return 0; + ra_tuple *a = bpf_map_lookup_elem(&psid_count, apsid); // a指向psid_count的apsid的内容 + if (!a) + return 0; + a->truth++; // 已访问 + bpf_map_delete_elem(&page_psid, &page); // 删除page_psid的page对应的内容 + return 0; +} + +const char LICENSE[] SEC("license") = "GPL"; \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/template.bpf.c b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/template.bpf.c new file mode 100644 index 000000000..05afde659 --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/template.bpf.c @@ -0,0 +1,14 @@ + +#include "vmlinux.h" +#include +#include +#include + +#include "sa_ebpf.h" +#include "bpf/template.h" +#include "task.h" + +DeclareCommonMaps(__u32); +DeclareCommonVar(); + +const char LICENSE[] SEC("license") = "GPL"; \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/eBPFStackCollector.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/eBPFStackCollector.h new file mode 100644 index 000000000..ce231e819 --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/eBPFStackCollector.h @@ -0,0 +1,125 @@ +#ifndef _SA_STACK_COLLECTOR_H__ +#define _SA_STACK_COLLECTOR_H__ + +#include +#include +#include +#include +#include "sa_user.h" + +struct Scale +{ + const char *Type, *Unit; + int64_t Period; +}; + +/// @brief count类,主要是为了重载比较运算,便于自动排序 +struct CountItem +{ + psid k; + double v; + CountItem(psid k, double v) : k(k), v(v){}; + + /// @brief count对象的大小取决于val的大小 + /// @param b 要比较的对象 + /// @return 小于b则为真,否则为假 + friend bool operator<(const CountItem a, const CountItem b); +}; + +class StackCollector +{ +protected: + struct bpf_object *obj = NULL; + + // 默认显示计数的变化情况,即每次输出数据后清除计数 + bool showDelta = true; + +public: + Scale scale = {0}; + + int pid = -1; // 用于设置ebpf程序跟踪的pid + int err = 0; // 用于保存错误代码 + + bool ustack = true; // 是否跟踪用户栈 + bool kstack = true; // 是否跟踪内核栈 + uint64_t min = 0; + uint64_t max = __UINT64_MAX__; // 设置采集指标最大值,最小值 + + int self_pid = -1; + +protected: + std::vector *sortedCountList(void); + + /// @brief 将缓冲区的数据解析为特定值 + /// @param 无 + /// @return 解析出的值 + virtual double count_value(void *data) = 0; + +public: + StackCollector(); + operator std::string(); + + /// @brief 负责ebpf程序的加载、参数设置和打开操作 + /// @param 无 + /// @return 成功则返回0,否则返回负数 + virtual int load(void) = 0; + + /// @brief 将ebpf程序挂载到跟踪点上 + /// @param 无 + /// @return 成功则返回0,否则返回负数 + virtual int attach(void) = 0; + + /// @brief 断开ebpf的跟踪点和处理函数间的连接 + /// @param 无 + virtual void detach(void) = 0; + + /// @brief 卸载ebpf程序 + /// @param 无 + virtual void unload(void) = 0; + +// 声明eBPF骨架 +#define declareEBPF(func) struct func##_bpf *skel = NULL; + +/// @brief 加载、初始化参数并打开指定类型的ebpf程序 +/// @param ... 一些ebpf程序全局变量初始化语句 +/// @note 失败会使上层函数返回-1 +#define StackProgLoadOpen(...) \ + { \ + skel = skel->open(NULL); \ + CHECK_ERR(!skel, "Fail to open BPF skeleton"); \ + skel->bss->min = min; \ + skel->bss->max = max; \ + skel->bss->u = ustack; \ + skel->bss->k = kstack; \ + skel->bss->self_pid = self_pid; \ + __VA_ARGS__; \ + err = skel->load(skel); \ + CHECK_ERR(err, "Fail to load BPF skeleton"); \ + obj = skel->obj; \ + } + +#define defaultAttach \ + { \ + err = skel->attach(skel); \ + CHECK_ERR(err, "Failed to attach BPF skeleton"); \ + } + +#define defaultDetach \ + { \ + if (skel) \ + { \ + skel->detach(skel); \ + } \ + } + +#define defaultUnload \ + { \ + if (skel) \ + { \ + skel->destroy(skel); \ + } \ + skel = NULL; \ + } +}; + +#endif \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/io.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/io.h new file mode 100644 index 000000000..bdcb68196 --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/io.h @@ -0,0 +1,41 @@ +#ifndef _SA_IO_H__ +#define _SA_IO_H__ + +#include +typedef struct +{ + __u64 size : 40; + __u64 count : 24; +} io_tuple; + +#ifdef __cplusplus +#include "io.skel.h" +#include "bpf/eBPFStackCollector.h" + +class IOStackCollector : public StackCollector +{ +private: + declareEBPF(io); + +public: + enum io_mod + { + COUNT, + SIZE, + AVE, + } DataType = COUNT; + +protected: + virtual double count_value(void *); + +public: + void setScale(io_mod mod); + IOStackCollector(); + virtual int load(void); + virtual int attach(void); + virtual void detach(void); + virtual void unload(void); +}; +#endif + +#endif \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/mem.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/mem.h new file mode 100644 index 000000000..ae6dbf309 --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/mem.h @@ -0,0 +1,90 @@ +#ifndef _SA_MEMORY_H__ +#define _SA_MEMORY_H__ + +#include "bpf/eBPFStackCollector.h" +#include "mem.skel.h" +#include + +class MemoryStackCollector : public StackCollector +{ +private: + struct mem_bpf *skel = __null; + +public: + char *object = (char *)"libc.so.6"; + +protected: + virtual double count_value(void *d); + +public: + MemoryStackCollector(); + + virtual int load(void); + virtual int attach(void); + virtual void detach(void); + virtual void unload(void); + +/// @brief 向指定用户函数附加一个ebpf处理函数 +/// @param skel ebpf程序骨架 +/// @param sym_name 用户态函数名字面量,不加双引号 +/// @param prog_name ebpf处理函数,skel->progs中的成员名 +/// @param is_retprobe 布尔类型,是否附加到符号返回处 +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0) +#define ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe) \ + do \ + { \ + DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts, \ + .retprobe = is_retprobe); \ + skel->links.prog_name = bpf_program__attach_uprobe_opts( \ + skel->progs.prog_name, \ + pid, \ + object, \ + 1, \ + &uprobe_opts); \ + } while (false) +#else +#define ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe) \ + do \ + { \ + LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts, \ + .retprobe = is_retprobe, \ + .func_name = #sym_name); \ + skel->links.prog_name = \ + bpf_program__attach_uprobe_opts( \ + skel->progs.prog_name, \ + pid, \ + object, \ + 0, \ + &uprobe_opts); \ + } while (false) +#endif + +/// @brief 向指定用户函数附加一个处理函数并检查是否连接成功 +/// @param skel ebpf程序骨架 +/// @param sym_name 要连接的用户函数 +/// @param prog_name ebpf处理函数 +/// @param is_retprobe 布尔类型,是否附加到函数返回处 +/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 +#define ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, is_retprobe) \ + do \ + { \ + ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe); \ + CHECK_ERR(!skel->links.prog_name, "no program attached for " #prog_name "\n") \ + } while (false) + +/// @brief 向指定用户态函数入口处附加一个处理函数并检查是否连接成功 +/// @param skel ebpf程序骨架 +/// @param sym_name 要跟踪的用户态函数名字面量,不带双引号 +/// @param prog_name ebpf处理函数,skel->progs中的成员 +/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 +#define at_ent(skel, sym_name, prog_name) ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, false) + +/// @brief 向指定用户态函数返回处附加一个处理函数并检查是否连接成功 +/// @param skel ebpf程序骨架 +/// @param sym_name 要附加的用户态函数名,字面量,不带双引号 +/// @param prog_name ebpf处理函数,skel->progs中的成员 +/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 +#define at_ret(skel, sym_name, prog_name) ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, true) +}; + +#endif diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/off_cpu.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/off_cpu.h new file mode 100644 index 000000000..95765ee3d --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/off_cpu.h @@ -0,0 +1,23 @@ +#ifndef _SA_OFF_CPU_H__ +#define _SA_OFF_CPU_H__ + +#include "bpf/eBPFStackCollector.h" +#include "off_cpu.skel.h" + +class OffCPUStackCollector : public StackCollector +{ +private: + struct off_cpu_bpf *skel = __null; + +protected: + virtual double count_value(void*); + +public: + OffCPUStackCollector(); + virtual int load(void); + virtual int attach(void); + virtual void detach(void); + virtual void unload(void); +}; + +#endif \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/on_cpu.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/on_cpu.h new file mode 100644 index 000000000..015f8b8c7 --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/on_cpu.h @@ -0,0 +1,32 @@ +#ifndef _SA_ON_CPU_H__ +#define _SA_ON_CPU_H__ + +#include "eBPFStackCollector.h" +#include "on_cpu.skel.h" + + +#ifdef __cplusplus +class OnCPUStackCollector : public StackCollector +{ +private: + struct on_cpu_bpf *skel = __null; + + int *pefds = NULL; + int num_cpus = 0; + struct bpf_link **links = NULL; + unsigned long long freq = 49; + +protected: + virtual double count_value(void *); + +public: + void setScale(uint64_t freq); + OnCPUStackCollector(); + virtual int load(void); + virtual int attach(void); + virtual void detach(void); + virtual void unload(void); +}; +#endif + +#endif \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/probe.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/probe.h new file mode 100644 index 000000000..ca15e3108 --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/probe.h @@ -0,0 +1,22 @@ +#include "bpf/eBPFStackCollector.h" +#include "probe.skel.h" + +class StackCountStackCollector : public StackCollector +{ +private: + struct probe_bpf *skel = __null; + +public: + std::string probe; + +protected: + virtual double count_value(void *); + +public: + void setScale(std::string probe); + StackCountStackCollector(); + virtual int load(void); + virtual int attach(void); + virtual void detach(void); + virtual void unload(void); +}; diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/readahead.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/readahead.h new file mode 100644 index 000000000..034df9fdd --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/readahead.h @@ -0,0 +1,32 @@ +#ifndef _SA_READAHEAD_H__ +#define _SA_READAHEAD_H__ + +#include +typedef struct +{ + __u32 expect; + __u32 truth; +} ra_tuple; + +#ifdef __cplusplus +#include "readahead.skel.h" +#include "bpf/eBPFStackCollector.h" + +class ReadaheadStackCollector : public StackCollector +{ +private: + declareEBPF(readahead); + +protected: + virtual double count_value(void *data); + +public: + ReadaheadStackCollector(); + virtual int load(void); + virtual int attach(void); + virtual void detach(void); + virtual void unload(void); +}; +#endif + +#endif \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/template.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/template.h new file mode 100644 index 000000000..ae8516fec --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/template.h @@ -0,0 +1,31 @@ +#ifndef _TEMPLATE_H__ +#define _TEMPLATE_H__ + +// ========== C code part ========== + +// ========== C code end ========== + +#ifdef __cplusplus +// ========== C++ code part ========== +#include "template.skel.h" +#include "bpf/eBPFStackCollector.h" + +class TemplateClass : public StackCollector +{ +private: + declareEBPF(template_bpf); + +protected: + virtual double count_value(void *); + +public: + TemplateClass(); + virtual int load(void); + virtual int attach(void); + virtual void detach(void); + virtual void unload(void); +}; +// ========== C++ code end ========== +#endif + +#endif \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/elf.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/dt_elf.h similarity index 96% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/elf.h rename to MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/dt_elf.h index 7e02c0ea9..a6174a376 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/elf.h +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/dt_elf.h @@ -13,7 +13,7 @@ #include #include -#include "symbol.h" +#include "dt_symbol.h" #define BUILD_ID_SIZE 40 bool save_symbol_cache(std::set &ss, const char *path); diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/symbol.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/dt_symbol.h similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/symbol.h rename to MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/dt_symbol.h diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_user.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_user.h index 790341cc9..cee3b9c19 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_user.h +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_user.h @@ -19,7 +19,6 @@ #ifndef STACK_ANALYZER_USER #define STACK_ANALYZER_USER -#include #include #include #include @@ -29,38 +28,6 @@ #include "sa_common.h" -struct Scale { - const char *Type, *Unit; - int64_t Period; -}; - -/// @brief 获取epbf程序中指定表的文件描述符 -/// @param name 表的名字 -#define OPEN_MAP(name) bpf_map__fd(skel->maps.name) - -/// @brief 获取所有表的文件描述符 -#define OPEN_ALL_MAP() \ - value_fd = OPEN_MAP(psid_count); \ - tgid_fd = OPEN_MAP(pid_tgid); \ - comm_fd = OPEN_MAP(pid_comm); \ - trace_fd = OPEN_MAP(stack_trace); - -/// @brief 加载、初始化参数并打开指定类型的ebpf程序 -/// @param ... 一些ebpf程序全局变量初始化语句 -/// @note 失败会使上层函数返回-1 -#define StackProgLoadOpen(...) \ - skel = skel->open(NULL); \ - CHECK_ERR(!skel, "Fail to open BPF skeleton"); \ - skel->bss->min = min; \ - skel->bss->max = max; \ - skel->bss->u = ustack; \ - skel->bss->k = kstack; \ - skel->bss->self_pid = self_pid; \ - __VA_ARGS__; \ - err = skel->load(skel); \ - CHECK_ERR(err, "Fail to load BPF skeleton"); \ - OPEN_ALL_MAP() - /// @brief 检查错误,若错误成立则打印带原因的错误信息并使上层函数返回-1 /// @param cond 被检查的条件表达式 /// @param info 要打印的错误信息 @@ -84,109 +51,4 @@ struct Scale { exit(EXIT_FAILURE); \ } -#include -#include -/// @brief staring perf event -/// @param hw_event attribution of the perf event -/// @param pid the pid to track. 0 for the calling process. -1 for all processes. -/// @param cpu the cpu to track. -1 for all cpu -/// @param group_fd fd of event group leader -/// @param flags setting -/// @return fd of perf event -static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, - unsigned long flags) -{ - return syscall(SYS_perf_event_open, hw_event, pid, cpu, group_fd, flags); -} - -extern int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz); - -/// @brief 向指定用户函数附加一个ebpf处理函数 -/// @param skel ebpf程序骨架 -/// @param sym_name 用户态函数名字面量,不加双引号 -/// @param prog_name ebpf处理函数,skel->progs中的成员名 -/// @param is_retprobe 布尔类型,是否附加到符号返回处 -#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0) -#define __ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe) \ - do \ - { \ - DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts, \ - .retprobe = is_retprobe); \ - skel->links.prog_name = bpf_program__attach_uprobe_opts( \ - skel->progs.prog_name, \ - pid, \ - object, \ - 1, \ - &uprobe_opts); \ - } while (false) -#else -#define __ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe) \ - do \ - { \ - LIBBPF_OPTS( \ - bpf_uprobe_opts, uprobe_opts, \ - .retprobe = is_retprobe, \ - .func_name = #sym_name); \ - skel->links.prog_name = bpf_program__attach_uprobe_opts( \ - skel->progs.prog_name, \ - pid, \ - object, \ - 0, \ - &uprobe_opts); \ - } while (false) -#endif - -/// @brief 检查处理函数是否已经被附加到函数上 -/// @param skel ebpf程序骨架 -/// @param prog_name ebpf处理函数 -/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 -#define __CHECK_PROGRAM(skel, prog_name) \ - do \ - { \ - if (!skel->links.prog_name) \ - { \ - fprintf(stderr, "[%s] no program attached for" #prog_name "\n", strerror(errno)); \ - return -errno; \ - } \ - } while (false) - -/// @brief 向指定用户函数附加一个处理函数并检查是否连接成功 -/// @param skel ebpf程序骨架 -/// @param sym_name 要连接的用户函数 -/// @param prog_name ebpf处理函数 -/// @param is_retprobe 布尔类型,是否附加到函数返回处 -/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 -#define __ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, is_retprobe) \ - do \ - { \ - __ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe); \ - __CHECK_PROGRAM(skel, prog_name); \ - } while (false) - -/// @brief 向指定用户态函数入口处附加一个处理函数 -/// @param skel ebpf程序骨架 -/// @param sym_name 要附加的用户态函数名 -/// @param prog_name ebpf处理函数 -#define ATTACH_UPROBE(skel, sym_name, prog_name) __ATTACH_UPROBE(skel, sym_name, prog_name, false) - -/// @brief 向指定用户态函数返回处附加一个处理函数 -/// @param skel ebpf程序骨架 -/// @param sym_name 用户态函数名 -/// @param prog_name ebpf处理函数 -#define ATTACH_URETPROBE(skel, sym_name, prog_name) __ATTACH_UPROBE(skel, sym_name, prog_name, true) - -/// @brief 向指定用户态函数入口处附加一个处理函数并检查是否连接成功 -/// @param skel ebpf程序骨架 -/// @param sym_name 要跟踪的用户态函数名字面量,不带双引号 -/// @param prog_name ebpf处理函数,skel->progs中的成员 -/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 -#define ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name) __ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, false) - -/// @brief 向指定用户态函数返回处附加一个处理函数并检查是否连接成功 -/// @param skel ebpf程序骨架 -/// @param sym_name 要附加的用户态函数名,字面量,不带双引号 -/// @param prog_name ebpf处理函数,skel->progs中的成员 -/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 -#define ATTACH_URETPROBE_CHECKED(skel, sym_name, prog_name) __ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, true) - #endif diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/eBPFStackCollector.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/eBPFStackCollector.cpp new file mode 100644 index 000000000..ea8284840 --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/eBPFStackCollector.cpp @@ -0,0 +1,218 @@ +#include "bpf/eBPFStackCollector.h" +#include "sa_user.h" +#include "dt_symbol.h" + +#include +#include +#include +#include + +std::string getLocalDateTime(void) +{ + auto t = time(NULL); + auto localTm = localtime(&t); + char buff[32]; + strftime(buff, 32, "%Y%m%d_%H_%M_%S", localTm); + return std::string(buff); +}; + +bool operator<(const CountItem a, const CountItem b) +{ + if (a.v < b.v || (a.v == b.v && a.k.pid < b.k.pid)) + return true; + else + return false; +} + +StackCollector::StackCollector() +{ + self_pid = getpid(); +}; + +std::vector *StackCollector::sortedCountList(void) +{ + auto psid_count = bpf_object__find_map_by_name(obj, "psid_count"); + auto val_size = bpf_map__value_size(psid_count); + auto value_fd = bpf_object__find_map_fd_by_name(obj, "psid_count"); + + auto keys = new psid[MAX_ENTRIES]; + auto vals = new char[MAX_ENTRIES * val_size]; + uint32_t count = MAX_ENTRIES; + psid next_key; + int err; + if (showDelta) + { + err = bpf_map_lookup_and_delete_batch(value_fd, NULL, &next_key, keys, vals, &count, NULL); + } + else + { + err = bpf_map_lookup_batch(value_fd, NULL, &next_key, keys, vals, &count, NULL); + } + if (err == EFAULT) + { + return NULL; + } + + auto D = new std::vector(); + for (uint32_t i = 0; i < count; i++) + { + CountItem d(keys[i], count_value(vals + val_size * i)); + D->insert(std::lower_bound(D->begin(), D->end(), d), d); + } + delete[] keys; + delete[] vals; + return D; +}; + +StackCollector::operator std::string() +{ + std::ostringstream oss; + oss << "Type:" << scale.Type << " Unit:" << scale.Unit << " Period:" << scale.Period << '\n'; + oss << "time:" << getLocalDateTime() << '\n'; + std::map> traces; + + oss << "counts:\n"; + { + auto D = sortedCountList(); + if (!D) + return oss.str(); + oss << "pid\tusid\tksid\tcount\n"; + uint64_t trace[MAX_STACKS], *p; + for (auto i : *D) + { + auto &id = i.k; + auto &v = i.v; + auto trace_fd = bpf_object__find_map_fd_by_name(obj, "stack_trace"); + oss << id.pid << '\t' << id.usid << '\t' << id.ksid << '\t' << v << '\n'; + 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--) + ; + for (; p >= trace; p--) + { + 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)) + ; + 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 << (addr - sym.start); + sym.name += ss.str(); + g_symbol_parser.putin_symbol_cache(id.pid, addr, sym.name); + } + else + { + std::stringstream ss(""); + ss << "0x" << std::hex << addr; + sym.name = ss.str(); + g_symbol_parser.putin_symbol_cache(id.pid, addr, sym.name); + } + clearSpace(sym.name); + traces[id.usid].push_back(sym.name); + } + } + if (id.ksid > 0 && traces.find(id.ksid) == traces.end()) + { + bpf_map_lookup_elem(trace_fd, &id.ksid, trace); + for (p = trace + MAX_STACKS - 1; !*p; p--) + ; + for (; p >= trace; p--) + { + uint64_t &addr = *p; + symbol sym; + sym.reset(addr); + if (g_symbol_parser.find_kernel_symbol(sym)) + ; + else + { + std::stringstream ss(""); + ss << "0x" << std::hex << addr; + sym.name = ss.str(); + g_symbol_parser.putin_symbol_cache(pid, addr, sym.name); + } + clearSpace(sym.name); + traces[id.ksid].push_back(sym.name); + } + } + } + delete D; + } + + oss << "traces:\n"; + { + oss << "sid\ttrace\n"; + for (auto i : traces) + { + oss << i.first << "\t"; + for (auto s : i.second) + { + oss << s << ';'; + } + oss << "\n"; + } + } + + oss << "groups:\n"; + { + auto tgid_fd = bpf_object__find_map_fd_by_name(obj, "pid_tgid"); + if (tgid_fd < 0) + { + return oss.str(); + } + auto keys = new uint32_t[MAX_ENTRIES]; + auto vals = new uint32_t[MAX_ENTRIES]; + uint32_t count = MAX_ENTRIES; + uint32_t next_key; + int err = bpf_map_lookup_batch(tgid_fd, NULL, &next_key, keys, vals, + &count, NULL); + if (err == EFAULT) + { + return oss.str(); + } + oss << "pid\ttgid\n"; + for (uint32_t i = 0; i < count; i++) + { + oss << keys[i] << '\t' << vals[i] << '\n'; + } + delete[] keys; + delete[] vals; + } + + oss << "commands:\n"; + { + auto comm_fd = bpf_object__find_map_fd_by_name(obj, "pid_comm"); + if (comm_fd < 0) + { + return oss.str(); + } + auto keys = new uint32_t[MAX_ENTRIES]; + auto vals = new char[MAX_ENTRIES][16]; + uint32_t count = MAX_ENTRIES; + uint32_t next_key; + int err = bpf_map_lookup_batch(comm_fd, NULL, &next_key, keys, vals, + &count, NULL); + if (err == EFAULT) + { + return oss.str(); + } + oss << "pid\tcommand\n"; + for (uint32_t i = 0; i < count; i++) + { + oss << keys[i] << '\t' << vals[i] << '\n'; + } + delete[] keys; + delete[] vals; + } + + oss << "OK\n"; + return oss.str(); +} \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/io.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/io.cpp new file mode 100644 index 000000000..b6284394b --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/io.cpp @@ -0,0 +1,55 @@ + +#include "bpf/io.h" + +double IOStackCollector::count_value(void *data) +{ + io_tuple *p = (io_tuple *)data; + switch (DataType) + { + case AVE: + return 1. * p->size / p->count; + case SIZE: + return p->size; + case COUNT: + return p->count; + default: + return 0; + } +}; + +void IOStackCollector::setScale(io_mod mod) +{ + DataType = mod; + static const char *Types[] = {"IOCount", "IOSize", "AverageIOSize"}; + static const char *Units[] = {"counts", "bytes", "bytes"}; + scale.Type = Types[mod]; + scale.Unit = Units[mod]; + scale.Period = 1; +}; + +IOStackCollector::IOStackCollector() +{ + setScale(DataType); +}; + +int IOStackCollector::load(void) +{ + StackProgLoadOpen(); + return 0; +} + +int IOStackCollector::attach(void) +{ + defaultAttach; + return 0; +} + +void IOStackCollector::detach(void) +{ + defaultDetach; +} + +void IOStackCollector::unload(void) +{ + defaultUnload; +} diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/mem.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/mem.cpp new file mode 100644 index 000000000..b26a7bc23 --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/mem.cpp @@ -0,0 +1,66 @@ +#include "bpf/mem.h" + +double MemoryStackCollector::count_value(void *d) +{ + return *(uint64_t *)d; +} + +MemoryStackCollector::MemoryStackCollector() +{ + kstack = false; + showDelta = false; + scale.Period = 1; + scale.Type = "LeakedMomery"; + scale.Unit = "bytes"; +}; + +int MemoryStackCollector::load(void) +{ + StackProgLoadOpen(); + return 0; +}; + +int MemoryStackCollector::attach(void) +{ + at_ent(skel, malloc, malloc_enter); + at_ret(skel, malloc, malloc_exit); + at_ent(skel, calloc, calloc_enter); + at_ret(skel, calloc, calloc_exit); + at_ent(skel, realloc, realloc_enter); + at_ret(skel, realloc, realloc_exit); + at_ent(skel, free, free_enter); + + at_ent(skel, mmap, mmap_enter); + at_ret(skel, mmap, mmap_exit); + at_ent(skel, munmap, munmap_enter); + + err = skel->attach(skel); + CHECK_ERR(err, "Failed to attach BPF skeleton"); + return 0; +}; + +void MemoryStackCollector::detach(void) +{ + skel->detach(skel); +#define des(name) \ + if (skel->links.name) \ + { \ + bpf_link__destroy(skel->links.name); \ + } + + des(malloc_enter); + des(malloc_exit); + des(calloc_enter); + des(calloc_exit); + des(realloc_enter); + des(realloc_exit); + des(free_enter); + des(mmap_enter); + des(mmap_exit); + des(munmap_enter); +}; + +void MemoryStackCollector::unload(void) +{ + defaultUnload; +} \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/off_cpu.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/off_cpu.cpp new file mode 100644 index 000000000..589f839fd --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/off_cpu.cpp @@ -0,0 +1,33 @@ +#include "bpf/off_cpu.h" + +OffCPUStackCollector::OffCPUStackCollector() +{ + scale.Period = 1 << 20; + scale.Type = "OffCPUTime"; + scale.Unit = "milliseconds"; +}; + +double OffCPUStackCollector::count_value(void *data) +{ + return *(uint32_t *)data; +}; + +int OffCPUStackCollector::load(void) +{ + StackProgLoadOpen(skel->bss->apid = pid;); + return 0; +} + +int OffCPUStackCollector::attach(void) +{ + defaultAttach; + return 0; +} + +void OffCPUStackCollector::detach(void) { + defaultDetach; +} + +void OffCPUStackCollector::unload(void) { + defaultUnload; +} \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/on_cpu.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/on_cpu.cpp new file mode 100644 index 000000000..587395aa7 --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/on_cpu.cpp @@ -0,0 +1,124 @@ +#include "bpf/on_cpu.h" +#include +#include + +/// @brief staring perf event +/// @param hw_event attribution of the perf event +/// @param pid the pid to track. 0 for the calling process. -1 for all processes. +/// @param cpu the cpu to track. -1 for all cpu +/// @param group_fd fd of event group leader +/// @param flags setting +/// @return fd of perf event +static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, + unsigned long flags) +{ + return syscall(SYS_perf_event_open, hw_event, pid, cpu, group_fd, flags); +} + +extern "C" +{ + extern int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz); +} + +OnCPUStackCollector::OnCPUStackCollector() +{ + setScale(freq); +}; + +void OnCPUStackCollector::setScale(uint64_t freq) +{ + this->freq = freq; + scale.Period = 1e9 / freq; + scale.Type = "OnCPUTime"; + scale.Unit = "nanoseconds"; +} + +double OnCPUStackCollector::count_value(void *data) +{ + return *(uint32_t *)data; +}; + +int OnCPUStackCollector::load(void) +{ + FILE *fp = popen("cat /proc/kallsyms | grep \" avenrun\"", "r"); + CHECK_ERR(!fp, "Failed to draw flame graph"); + unsigned long *load_a; + fscanf(fp, "%p", &load_a); + pclose(fp); + StackProgLoadOpen(skel->bss->load_a = load_a;); + + return 0; +}; + +int OnCPUStackCollector::attach(void) +{ + const char *online_cpus_file = "/sys/devices/system/cpu/online"; + bool *online_mask; + int num_online_cpus; + err = parse_cpu_mask_file(online_cpus_file, &online_mask, &num_online_cpus); + CHECK_ERR(err, "Fail to get online CPU numbers"); + + num_cpus = libbpf_num_possible_cpus(); + CHECK_ERR(num_cpus <= 0, "Fail to get the number of processors"); + + struct perf_event_attr attr = { + .type = PERF_TYPE_SOFTWARE, // hardware event can't be used + .size = sizeof(attr), + .config = PERF_COUNT_SW_CPU_CLOCK, + .sample_freq = freq, + .inherit = 1, + .freq = 1, // use freq instead of period + }; + pefds = (int *)malloc(num_cpus * sizeof(int)); + for (int i = 0; i < num_cpus; i++) + { + pefds[i] = -1; + } + links = (struct bpf_link **)calloc(num_cpus, sizeof(struct bpf_link *)); + for (int cpu = 0; cpu < num_cpus; cpu++) + { + /* skip offline/not present CPUs */ + if (cpu >= num_online_cpus || !online_mask[cpu]) + { + continue; + } + /* Set up performance monitoring on a CPU/Core */ + int pefd = perf_event_open(&attr, pid, cpu, -1, 0); + CHECK_ERR(pefd < 0, "Fail to set up performance monitor on a CPU/Core"); + pefds[cpu] = pefd; + /* Attach a BPF program on a CPU */ + links[cpu] = bpf_program__attach_perf_event(skel->progs.do_stack, pefd); // 与内核bpf程序联系 + CHECK_ERR(!links[cpu], "Fail to attach bpf program"); + } + return 0; +} + +void OnCPUStackCollector::detach(void) +{ + if (links) + { + for (int cpu = 0; cpu < num_cpus; cpu++) + { + bpf_link__destroy(links[cpu]); + } + free(links); + links = NULL; + } + if (pefds) + { + for (int i = 0; i < num_cpus; i++) + { + if (pefds[i] >= 0) + { + close(pefds[i]); + } + } + free(pefds); + pefds = NULL; + } +}; + +void OnCPUStackCollector::unload(void) +{ + defaultUnload; +}; diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/probe.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/probe.cpp new file mode 100644 index 000000000..e3407553e --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/probe.cpp @@ -0,0 +1,44 @@ +#include "bpf/probe.h" + +double StackCountStackCollector::count_value(void *data) { + return *(uint32_t*)data; +} + +StackCountStackCollector::StackCountStackCollector() +{ + scale = { + .Type = "StackCounts", + .Unit = "Counts", + .Period = 1, + }; +}; + +void StackCountStackCollector::setScale(std::string probe) +{ + this->probe = probe; + scale.Type = (probe + scale.Type).c_str(); +}; + +int StackCountStackCollector::load(void) +{ + StackProgLoadOpen(); + return 0; +}; + +int StackCountStackCollector::attach(void) +{ + skel->links.handle = + bpf_program__attach_kprobe(skel->progs.handle, false, probe.c_str()); + CHECK_ERR(!skel->links.handle, "Fail to attach kprobe"); + return 0; +}; + +void StackCountStackCollector::detach(void) +{ + defaultDetach; +}; + +void StackCountStackCollector::unload(void) +{ + defaultUnload; +}; diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/readahead.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/readahead.cpp new file mode 100644 index 000000000..e3c09bf09 --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/readahead.cpp @@ -0,0 +1,39 @@ +#include "bpf/readahead.h" + +double ReadaheadStackCollector::count_value(void *data) +{ + ra_tuple *p = (ra_tuple *)data; + return p->expect - p->truth; +}; + +ReadaheadStackCollector::ReadaheadStackCollector() +{ + showDelta = false; + scale = { + .Type = "UnusedReadaheadPages", + .Unit = "pages", + .Period = 1, + }; +}; + +int ReadaheadStackCollector::load(void) +{ + StackProgLoadOpen(); + return 0; +} + +int ReadaheadStackCollector::attach(void) +{ + defaultAttach; + return 0; +} + +void ReadaheadStackCollector::detach(void) +{ + defaultDetach; +} + +void ReadaheadStackCollector::unload(void) +{ + defaultUnload; +} \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/template.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/template.cpp new file mode 100644 index 000000000..10f0ca216 --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/template.cpp @@ -0,0 +1,26 @@ +#include "bpf/template.h" + +// ========== implement virtual func ========== + +double TemplateClass::count_value(void *data) +{ + return *(uint32_t*)data; +}; + +int TemplateClass::load(void) +{ + return 0; +}; + +int TemplateClass::attach(void) +{ + return 0; +}; + +void TemplateClass::detach(void){}; + +void TemplateClass::unload(void){}; + +// ========== other implementations ========== + +TemplateClass::TemplateClass(){}; \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/elf.cc b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/dt_elf.cpp similarity index 98% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/elf.cc rename to MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/dt_elf.cpp index f58e76566..d040e8936 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/elf.cc +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/dt_elf.cpp @@ -6,6 +6,8 @@ * License terms: GNU General Public License (GPL) version 3 * */ +#include "dt_elf.h" + #include #include #include @@ -16,12 +18,6 @@ #include #include -<<<<<<<< HEAD:eBPF_Supermarket/Stack_Analyser/src/elf.cc -#include "elf.hpp" -======== -#include "stack_analyzer/include/elf.h" ->>>>>>>> 642a5109ef5dd10a13d3e9a905aefffb9dfdb467:MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/elf.cc - #define NOTE_ALIGN(n) (((n) + 3) & -4U) struct sym_section_ctx diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/symbol.cc b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/dt_symbol.cpp similarity index 99% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/symbol.cc rename to MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/dt_symbol.cpp index 44d65b7af..921fff048 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/symbol.cc +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/dt_symbol.cpp @@ -12,8 +12,8 @@ #include #include -#include "stack_analyzer/include/symbol.h" -#include "stack_analyzer/include/elf.h" +#include "dt_symbol.h" +#include "dt_elf.h" void restore_global_env(); int attach_ns_env(int pid); diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/main.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/main.cpp new file mode 100644 index 000000000..7cc136abf --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/main.cpp @@ -0,0 +1,200 @@ +#include +#include + +#include "bpf/on_cpu.h" +#include "bpf/off_cpu.h" +#include "bpf/mem.h" +#include "bpf/io.h" +#include "bpf/readahead.h" +#include "bpf/probe.h" + +#include "sa_user.h" +#include "clipp.h" + + +namespace MainConfig +{ + int run_time = __INT_MAX__; // 运行时间 + unsigned delay = 5; // 设置输出间隔 + std::string command = ""; + int32_t target_pid = -1; +} + +std::vector StackCollectorList; + +void endCollect(void) +{ + signal(SIGINT, SIG_IGN); + for (auto Item : StackCollectorList) + { + if (MainConfig::run_time > 0) + { + std::cout << std::string(*Item) << std::endl; + } + Item->detach(); + Item->unload(); + } + if (MainConfig::command.length()) + { + kill(MainConfig::target_pid, SIGTERM); + } +} + +uint64_t IntTmp; +std::string StrTmp; + +int main(int argc, char *argv[]) +{ + auto MainOption = (( + ((clipp::option("-p", "--pid") & clipp::value("pid of sampled process, default -1 for all", MainConfig::target_pid)) % "set pid of process to monitor") | + ((clipp::option("-c", "--command") & clipp::value("to be sampled command to run, default none", MainConfig::command)) % "set command for monitoring the whole life")), + (clipp::option("-d", "--delay") & clipp::value("delay time(seconds) to output, default 5", MainConfig::delay)) % "set the interval to output", + (clipp::option("-t", "--timeout") & clipp::value("run time, default nearly infinite", MainConfig::run_time)) % "set the total simpling time"); + + auto SubOption = (clipp::option("-U", "--user-stack-only").call([] + { StackCollectorList.back()->kstack = false; }) % + "only sample user stacks", + clipp::option("-K", "--kernel-stack-only").call([] + { StackCollectorList.back()->ustack = false; }) % + "only sample kernel stacks", + (clipp::option("-m", "--max-value") & clipp::value("max threshold of sampled value", IntTmp).call([] + { StackCollectorList.back()->max = IntTmp; })) % + "set the max threshold of sampled value", + (clipp::option("-n", "--min-value") & clipp::value("min threshold of sampled value", IntTmp).call([] + { StackCollectorList.back()->min = IntTmp; })) % + "set the min threshold of sampled value"); + + auto OnCpuOption = (clipp::option("on_cpu").call([] + { StackCollectorList.push_back(new OnCPUStackCollector()); }) % + "sample the call stacks of on-cpu processes") & + (clipp::option("-F", "--frequency") & clipp::value("sampling frequency", IntTmp).call([] + { static_cast(StackCollectorList.back())->setScale(IntTmp); }) % + "sampling at a set frequency", + SubOption); + + auto OffCpuOption = clipp::option("off_cpu").call([] + { StackCollectorList.push_back(new OffCPUStackCollector()); }) % + "sample the call stacks of off-cpu processes" & + SubOption; + + auto MemoryOption = clipp::option("mem").call([] + { StackCollectorList.push_back(new MemoryStackCollector()); }) % + "sample the memory usage of call stacks" & + SubOption; + + auto IOOption = clipp::option("io").call([] + { StackCollectorList.push_back(new IOStackCollector()); }) % + "sample the IO data volume of call stacks" & + ((clipp::option("--mod") & (clipp::option("count").call([] + { static_cast(StackCollectorList.back())->setScale(IOStackCollector::io_mod::COUNT); }) % + "Counting the number of I/O operations" | + clipp::option("ave").call([] + { static_cast(StackCollectorList.back())->setScale(IOStackCollector::io_mod::AVE); }) % + "Counting the ave of I/O operations" | + clipp::option("size").call([] + { static_cast(StackCollectorList.back())->setScale(IOStackCollector::io_mod::SIZE); }) % + "Counting the size of I/O operations")) % + "set the statistic mod", + SubOption); + + auto ReadaheadOption = clipp::option("readahead").call([] + { StackCollectorList.push_back(new ReadaheadStackCollector()); }) % + "sample the readahead hit rate of call stacks" & + SubOption; + auto StackCountOption = clipp::option("probe").call([] + { StackCollectorList.push_back(new StackCountStackCollector()); }) % + "sample the counts of calling stacks" & + (clipp::option("-S", "--String") & clipp::value("probe String", StrTmp).call([] + { static_cast(StackCollectorList.back())->setScale(StrTmp); }) % + "sampling at a set probe string", + SubOption); + + auto cli = (MainOption, + clipp::option("-v", "--version").call([] + { std::cout << "verion 2.0\n\n"; }) % + "show version", + OnCpuOption, + OffCpuOption, + MemoryOption, + IOOption, + ReadaheadOption, + StackCountOption) % + "statistic call trace relate with some metrics"; + + if (!clipp::parse(argc, argv, cli)) + { + std::cout << clipp::make_man_page(cli, argv[0]) << '\n'; + return 0; + } + + uint64_t eventbuff = 1; + int child_exec_event_fd = eventfd(0, EFD_CLOEXEC); + CHECK_ERR(child_exec_event_fd < 0, "failed to create event fd"); + if (MainConfig::command.length()) + { + MainConfig::target_pid = fork(); + switch (MainConfig::target_pid) + { + case -1: + { + std::cout << "command create failed." << std::endl; + return -1; + } + case 0: + { + const auto bytes = read(child_exec_event_fd, &eventbuff, sizeof(eventbuff)); + CHECK_ERR(bytes < 0, "failed to read from fd %ld", bytes) + else CHECK_ERR(bytes != sizeof(eventbuff), "read unexpected size %ld", bytes); + printf("child exec %s\n", MainConfig::command.c_str()); + CHECK_ERR_EXIT(execl("/bin/bash", "bash", "-c", MainConfig::command.c_str(), NULL), "failed to execute child command"); + break; + } + default: + { + printf("create child %d\n", MainConfig::target_pid); + break; + } + } + } + + for (auto Item = StackCollectorList.begin(); Item != StackCollectorList.end();) + { + (*Item)->pid = MainConfig::target_pid; + if ((*Item)->load()) + { + goto err; + } + if ((*Item)->attach()) + { + goto err; + } + Item++; + continue; + err: + fprintf(stderr, "%s eBPF prog err\n", (*Item)->scale.Type); + (*Item)->detach(); + (*Item)->unload(); + Item = StackCollectorList.erase(Item); + } + + if (MainConfig::command.length()) + { + printf("wake up child\n"); + write(child_exec_event_fd, &eventbuff, sizeof(eventbuff)); + } + + // printf("display mode: %d\n", MainConfig::d_mode); + + for (; MainConfig::run_time > 0 && (MainConfig::target_pid < 0 || !kill(MainConfig::target_pid, 0)); MainConfig::run_time -= MainConfig::delay) + { + sleep(MainConfig::delay); + for (auto Item : StackCollectorList) + { + Item->detach(); + std::cout << std::string(*Item); + Item->attach(); + } + } + + atexit(endCollect); +} \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/stack_analyzer.cc b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/stack_analyzer.cc deleted file mode 100644 index 7608fd839..000000000 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/stack_analyzer.cc +++ /dev/null @@ -1,934 +0,0 @@ -// Copyright 2023 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 用户态bpf的主程序代码,主要用于数据的显示和整理 - -#include -#include -#include -#include -#include -#include - -#include "stack_analyzer/include/symbol.h" -#include "stack_analyzer/include/clipp.h" - -extern "C" -{ -#include -#include -#include -#include -#include - -#include "stack_analyzer/include/sa_user.h" -#include "system_diagnosis/stack_analyzer/on_cpu_count.skel.h" -#include "system_diagnosis/stack_analyzer/off_cpu_count.skel.h" -#include "system_diagnosis/stack_analyzer/mem_count.skel.h" -#include "system_diagnosis/stack_analyzer/io_count.skel.h" -#include "system_diagnosis/stack_analyzer/pre_count.skel.h" -#include "system_diagnosis/stack_analyzer/stack_count.skel.h" -} - -void splitString(std::string symbol, const char split, std::vector &res) -{ - if (symbol == "") - return; - std::string strs = symbol + split; - size_t pos = strs.find(split); - while (pos != strs.npos) - { - std::string temp = strs.substr(0, pos); - res.push_back(temp); - strs = strs.substr(pos + 1, strs.size()); - pos = strs.find(split); - } -} - -std::string getLocalDateTime(void) -{ - auto t = time(NULL); - auto localTm = localtime(&t); - char buff[32]; - strftime(buff, 32, "%Y%m%d_%H_%M_%S", localTm); - return std::string(buff); -} - -// 模板用来统一调用多个类有同样但未被抽象的接口 -// 虚函数用来规范接口来被统一调用 - -class StackCollector -{ -private: - /// @brief count类,主要是为了重载比较运算,便于自动排序 - class CountItem - { - public: - uint32_t pid; - int32_t ksid, usid; - double val; - CountItem(int32_t p, int32_t k, int32_t u, double v) - { - - pid = p; - ksid = k; - usid = u; - val = v; - }; - - /// @brief count对象的大小取决于val的大小 - /// @param b 要比较的对象 - /// @return 小于b则为真,否则为假 - bool operator<(const CountItem b) - { - return val < b.val; - }; - }; - - /// @brief 从count_map中取出数据并按val值生成有序列表 - /// @return 一个列表指针 - std::vector *sortedCountList(void) - { - if (value_fd < 0) - { - return NULL; - } - auto keys = new psid[MAX_ENTRIES]; - auto vals = new char[MAX_ENTRIES * count_size]; - uint32_t count = MAX_ENTRIES; - psid next_key; - int err; - if (showDelta) - { - err = bpf_map_lookup_and_delete_batch(value_fd, NULL, &next_key, keys, vals, &count, NULL); - } - else - { - err = bpf_map_lookup_batch(value_fd, NULL, &next_key, keys, vals, &count, NULL); - } - if (err == EFAULT) - { - return NULL; - } - - auto D = new std::vector(); - for (uint32_t i = 0; i < count; i++) - { - CountItem d(keys[i].pid, keys[i].ksid, keys[i].usid, data_value(vals + count_size * i)); - D->insert(std::lower_bound(D->begin(), D->end(), d), d); - } - delete[] keys; - delete[] vals; - return D; - }; - -protected: - int value_fd = -1; // 栈计数表的文件描述符 - int tgid_fd = -1; // pid-tgid表的文件描述符 - int comm_fd = -1; // pid-进程名表的文件描述符 - int trace_fd = -1; // 栈id-栈轨迹表的文件描述符 - - // 计数变量类型默认为u32 - size_t count_size = sizeof(uint32_t); - - // 默认显示计数的变化情况,即每次输出数据后清除计数 - bool showDelta = true; - - /// @brief 将缓冲区的数据解析为特定值,默认解析为u32 - /// @param 无 - /// @return 解析出的值 - virtual double data_value(void *data) - { - return *(uint32_t *)data; - }; - - // 声明 -#define declareEBPF(eBPFName) struct eBPFName *skel = NULL; - -public: - Scale scale; - - int pid = -1; // 用于设置ebpf程序跟踪的pid - int cpu = -1; // 用于设置ebpf程序跟踪的cpu - int err = 0; // 用于保存错误代码 - - bool ustack = true; // 是否跟踪用户栈 - bool kstack = true; // 是否跟踪内核栈 - uint64_t min = 0; - uint64_t max = __UINT64_MAX__; // 设置采集指标最大值,最小值 - - bool clear = false; // 清除已输出的指标积累量 - int self_pid; - - StackCollector() - { - self_pid = getpid(); - }; - - /// @brief 负责ebpf程序的加载、参数设置和打开操作 - /// @param 无 - /// @return 成功则返回0,否则返回负数 - virtual int load(void) = 0; -#define defaultLoad \ - int load(void) override \ - { \ - StackProgLoadOpen(skel->bss->apid = pid); \ - return 0; \ - }; - - /// @brief 将ebpf程序挂载到跟踪点上 - /// @param 无 - /// @return 成功则返回0,否则返回负数 - virtual int attach(void) = 0; -#define defaultAttach \ - int attach(void) override \ - { \ - err = skel->attach(skel); \ - CHECK_ERR(err, "Failed to attach BPF skeleton"); \ - return 0; \ - }; - - /// @brief 断开ebpf的跟踪点和处理函数间的连接 - /// @param 无 - virtual void detach(void) = 0; -#define defaultDetach \ - void detach(void) override \ - { \ - if (skel) \ - { \ - skel->detach(skel); \ - } \ - }; - - /// @brief 卸载ebpf程序 - /// @param 无 - virtual void unload(void) = 0; -#define defaultUnload \ - void unload(void) override \ - { \ - if (skel) \ - { \ - skel->destroy(skel); \ - } \ - skel = NULL; \ - }; - - operator std::string() - { - std::ostringstream oss; - oss << "Type:" << scale.Type << " Unit:" << scale.Unit << " Period:" << scale.Period << '\n'; - oss << "time:" << getLocalDateTime() << '\n'; - std::map> traces; - oss << "counts:\n"; - { - auto D = sortedCountList(); - if (!D) - return oss.str(); - oss << "pid\tusid\tksid\tcount\n"; - uint64_t trace[MAX_STACKS], *p; - for (auto id : *D) - { - oss << id.pid << '\t' << id.usid << '\t' << id.ksid << '\t' << id.val - << '\n'; - 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--) - ; - for (; p >= trace; p--) - { - 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)) - ; - 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 << (addr - sym.start); - sym.name += ss.str(); - g_symbol_parser.putin_symbol_cache(id.pid, addr, sym.name); - } - else - { - std::stringstream ss(""); - ss << "0x" << std::hex << addr; - sym.name = ss.str(); - g_symbol_parser.putin_symbol_cache(id.pid, addr, sym.name); - } - clearSpace(sym.name); - traces[id.usid].push_back(sym.name); - } - } - if (id.ksid > 0 && traces.find(id.ksid) == traces.end()) - { - bpf_map_lookup_elem(trace_fd, &id.ksid, trace); - for (p = trace + MAX_STACKS - 1; !*p; p--) - ; - for (; p >= trace; p--) - { - uint64_t &addr = *p; - symbol sym; - sym.reset(addr); - if (g_symbol_parser.find_kernel_symbol(sym)) - ; - else - { - std::stringstream ss(""); - ss << "0x" << std::hex << addr; - sym.name = ss.str(); - g_symbol_parser.putin_symbol_cache(pid, addr, sym.name); - } - clearSpace(sym.name); - traces[id.ksid].push_back(sym.name); - } - } - } - delete D; - } - oss << "traces:\n"; - { - oss << "sid\ttrace\n"; - for (auto i : traces) - { - oss << i.first << "\t"; - for (auto s : i.second) - { - oss << s << ';'; - } - oss << "\n"; - } - } - oss << "groups:\n"; - { - if (tgid_fd < 0) - { - return oss.str(); - } - auto keys = new uint32_t[MAX_ENTRIES]; - auto vals = new uint32_t[MAX_ENTRIES]; - uint32_t count = MAX_ENTRIES; - uint32_t next_key; - int err = bpf_map_lookup_batch(tgid_fd, NULL, &next_key, keys, vals, - &count, NULL); - if (err == EFAULT) - { - return oss.str(); - } - oss << "pid\ttgid\n"; - for (uint32_t i = 0; i < count; i++) - { - oss << keys[i] << '\t' << vals[i] << '\n'; - } - delete[] keys; - delete[] vals; - } - oss << "commands:\n"; - { - if (comm_fd < 0) - { - return oss.str(); - } - auto keys = new uint32_t[MAX_ENTRIES]; - auto vals = new char[MAX_ENTRIES][16]; - uint32_t count = MAX_ENTRIES; - uint32_t next_key; - int err = bpf_map_lookup_batch(comm_fd, NULL, &next_key, keys, vals, - &count, NULL); - if (err == EFAULT) - { - return oss.str(); - } - oss << "pid\tcommand\n"; - for (uint32_t i = 0; i < count; i++) - { - oss << keys[i] << '\t' << vals[i] << '\n'; - } - delete[] keys; - delete[] vals; - } - oss << "OK\n"; - return oss.str(); - } -}; - -class OnCPUStackCollector : public StackCollector -{ -private: - declareEBPF(on_cpu_count_bpf); - const char *online_cpus_file = "/sys/devices/system/cpu/online"; - bool *online_mask = NULL; - int *pefds = NULL, num_cpus = 0, num_online_cpus = 0; - struct perf_event_attr attr = {0}; - struct bpf_link **links = NULL; - unsigned long long freq = 49; - -public: - OnCPUStackCollector() - { - setScale(freq); - err = parse_cpu_mask_file(online_cpus_file, &online_mask, &num_online_cpus); - CHECK_ERR_EXIT(err, "Fail to get online CPU numbers"); - num_cpus = libbpf_num_possible_cpus(); - CHECK_ERR_EXIT(num_cpus <= 0, "Fail to get the number of processors"); - }; - - void setScale(uint64_t freq) - { - this->freq = freq; - scale.Period = 1e9 / freq; - scale.Type = "OnCPUTime"; - scale.Unit = "nanoseconds"; - } - - int load(void) override - { - FILE *fp = popen("cat /proc/kallsyms | grep \" avenrun\"", "r"); - CHECK_ERR(!fp, "Failed to draw flame graph"); - unsigned long *load_a; - fscanf(fp, "%p", &load_a); - pclose(fp); - StackProgLoadOpen(skel->bss->load_a = load_a) return 0; - }; - - int attach(void) override - { - attr = { - .type = PERF_TYPE_SOFTWARE, // hardware event can't be used - .size = sizeof(attr), - .config = PERF_COUNT_SW_CPU_CLOCK, - .sample_freq = freq, - .inherit = 1, - .freq = 1, // use freq instead of period - }; - pefds = (int *)malloc(num_cpus * sizeof(int)); - for (int i = 0; i < num_cpus; i++) - { - pefds[i] = -1; - } - links = (struct bpf_link **)calloc(num_cpus, sizeof(struct bpf_link *)); - for (int cpu = 0; cpu < num_cpus; cpu++) - { - /* skip offline/not present CPUs */ - if (cpu >= num_online_cpus || !online_mask[cpu]) - { - continue; - } - /* Set up performance monitoring on a CPU/Core */ - int pefd = perf_event_open(&attr, pid, cpu, -1, 0); - CHECK_ERR(pefd < 0, "Fail to set up performance monitor on a CPU/Core"); - pefds[cpu] = pefd; - /* Attach a BPF program on a CPU */ - links[cpu] = bpf_program__attach_perf_event(skel->progs.do_stack, pefd); // 与内核bpf程序联系 - CHECK_ERR(!links[cpu], "Fail to attach bpf program"); - } - return 0; - } - - void detach(void) override - { - if (links) - { - for (int cpu = 0; cpu < num_cpus; cpu++) - { - - bpf_link__destroy(links[cpu]); - } - free(links); - links = NULL; - } - if (pefds) - { - for (int i = 0; i < num_cpus; i++) - { - if (pefds[i] >= 0) - { - close(pefds[i]); - } - } - free(pefds); - pefds = NULL; - } - } - - defaultUnload; -}; - -class OffCPUStackCollector : public StackCollector -{ -private: - declareEBPF(off_cpu_count_bpf); - -protected: - defaultLoad; - defaultAttach; - defaultDetach; - defaultUnload; - -public: - OffCPUStackCollector() - { - scale.Period = 1 << 20; - scale.Type = "OffCPUTime"; - scale.Unit = "milliseconds"; - }; -}; - -class MemoryStackCollector : public StackCollector -{ -private: - declareEBPF(mem_count_bpf); - -protected: - double data_value(void *d) override - { - return *(uint64_t *)d; - } - -public: - char *object = (char *)"libc.so.6"; - - MemoryStackCollector() - { - count_size = sizeof(uint64_t); - kstack = false; - showDelta = false; - scale.Period = 1; - scale.Type = "LeakedMomery"; - scale.Unit = "bytes"; - }; - - int load(void) override - { - StackProgLoadOpen(); - return 0; - }; - - int attach(void) override - { - ATTACH_UPROBE_CHECKED(skel, malloc, malloc_enter); - ATTACH_URETPROBE_CHECKED(skel, malloc, malloc_exit); - ATTACH_UPROBE_CHECKED(skel, calloc, calloc_enter); - ATTACH_URETPROBE_CHECKED(skel, calloc, calloc_exit); - ATTACH_UPROBE_CHECKED(skel, realloc, realloc_enter); - ATTACH_URETPROBE_CHECKED(skel, realloc, realloc_exit); - ATTACH_UPROBE_CHECKED(skel, free, free_enter); - - ATTACH_UPROBE_CHECKED(skel, mmap, mmap_enter); - ATTACH_URETPROBE_CHECKED(skel, mmap, mmap_exit); - ATTACH_UPROBE_CHECKED(skel, munmap, munmap_enter); - - err = skel->attach(skel); - CHECK_ERR(err, "Failed to attach BPF skeleton"); - return 0; - }; - - void detach(void) override - { - skel->detach(skel); -#define destoryBPFLinkIfExist(name) \ - if (skel->links.name) \ - { \ - bpf_link__destroy(skel->links.name); \ - } - destoryBPFLinkIfExist(malloc_enter); - destoryBPFLinkIfExist(malloc_exit); - destoryBPFLinkIfExist(calloc_enter); - destoryBPFLinkIfExist(calloc_exit); - destoryBPFLinkIfExist(realloc_enter); - destoryBPFLinkIfExist(realloc_exit); - destoryBPFLinkIfExist(free_enter); - destoryBPFLinkIfExist(mmap_enter); - destoryBPFLinkIfExist(mmap_exit); - destoryBPFLinkIfExist(munmap_enter); - }; - - defaultUnload; -}; - -class IOStackCollector : public StackCollector -{ -private: - declareEBPF(io_count_bpf); - -protected: - double data_value(void *data) override - { - io_tuple *p = (io_tuple *)data; - switch (DataType) - { - case AVE: - return 1. * p->size / p->count; - case SIZE: - return p->size; - case COUNT: - return p->count; - default: - return 0; - } - }; - -public: - typedef enum - { - COUNT, - SIZE, - AVE - } io_mod; - - io_mod DataType = io_mod::COUNT; - - void setScale(io_mod mod) - { - DataType = mod; - static const char *Types[] = {"IOCount", "IOSize", "AverageIOSize"}; - static const char *Units[] = {"counts", "bytes", "bytes"}; - scale.Type = Types[mod]; - scale.Unit = Units[mod]; - scale.Period = 1; - }; - - IOStackCollector() - { - count_size = sizeof(io_tuple); - setScale(DataType); - }; - - defaultLoad; - defaultAttach; - defaultDetach; - defaultUnload; -}; - -class ReadaheadStackCollector : public StackCollector -{ -private: - declareEBPF(pre_count_bpf); - -protected: - double data_value(void *data) override - { - ra_tuple *p = (ra_tuple *)data; - return p->expect - p->truth; - }; - -public: - defaultLoad; - defaultAttach; - defaultDetach; - defaultUnload; - - ReadaheadStackCollector() - { - count_size = sizeof(ra_tuple); - showDelta = false; - scale = { - .Type = "UnusedReadaheadPages", - .Unit = "pages", - .Period = 1, - }; - }; -}; - -class StackCountStackCollector : public StackCollector -{ -private: - declareEBPF(stack_count_bpf); - -public: - std::string probe = ""; // 保存命令行的输入 - std::string tp_class = ""; - std::vector strList; - typedef enum - { - KPROBE, - TRACEPOINT, - USTD_TP, - UPROBE - } stack_mod; - - stack_mod ProbeType = stack_mod::KPROBE; - - StackCountStackCollector() - { - scale = { - .Type = "StackCounts", - .Unit = "Counts", - .Period = 1, - }; - }; - - void setProbe(std::string probe) - { - splitString(probe, ':', strList); - if (strList.size() == 1) - { - // probe a kernel function - this->probe = probe; - } - else if (strList.size() == 3) - { - if (strList[0] == "p" && strList[1] == "") - { - // probe a kernel function - this->probe = strList[2]; - } - else if (strList[0] == "t") - { - // probe a kernel tracepoint - this->tp_class = strList[1]; - this->probe = strList[2]; - ProbeType = stack_mod::TRACEPOINT; - } - else if (strList[0] == "p" && strList[1] != "") - { - // probe a user-space function in the library 'lib' - ProbeType = stack_mod::UPROBE; - } - else if (strList[0] == "u") - { - // probe a USDT tracepoint - ProbeType = stack_mod::USTD_TP; - } - else - { - printf("Type must be 'p', 't', or 'u'"); - } - } - else if (strList.size() == 2) - { - // probe a user-space function in the library 'lib' - ProbeType = stack_mod::UPROBE; - } - else - { - printf("Too many args"); - } - scale.Type = (probe + scale.Type).c_str(); - } - - defaultLoad; - int attach(void) override - { - if (ProbeType == KPROBE) - { - skel->links.handle = - bpf_program__attach_kprobe(skel->progs.handle, false, - probe.c_str()); - CHECK_ERR(!skel->links.handle, "Fail to attach kprobe"); - } - else if (ProbeType == TRACEPOINT) - { - skel->links.handle_tp = - bpf_program__attach_tracepoint(skel->progs.handle_tp, tp_class.c_str(), probe.c_str()); - CHECK_ERR(!skel->links.handle_tp, "Fail to attach tracepoint"); - } - return 0; - }; - defaultDetach; - defaultUnload; -}; - -namespace MainConfig -{ -int run_time = __INT_MAX__; // 运行时间 -unsigned delay = 5; // 设置输出间隔 -std::string command = ""; -int32_t target_pid = -1; -} -std::vector StackCollectorList; -void endCollect(void) -{ - signal(SIGINT, SIG_IGN); - for (auto Item : StackCollectorList) - { - if (MainConfig::run_time > 0) - { - std::cout << std::string(*Item) << std::endl; - } - Item->detach(); - Item->unload(); - } - if (MainConfig::command.length()) - { - kill(MainConfig::target_pid, SIGTERM); - } -} - -uint64_t IntTmp; -std::string StrTmp; -int main(int argc, char *argv[]) -{ - auto MainOption = (( - ((clipp::option("-p", "--pid") & clipp::value("pid of sampled process, default -1 for all", MainConfig::target_pid)) % "set pid of process to monitor") | - ((clipp::option("-c", "--command") & clipp::value("to be sampled command to run, default none", MainConfig::command)) % "set command for monitoring the whole life")), - (clipp::option("-d", "--delay") & clipp::value("delay time(seconds) to output, default 5", MainConfig::delay)) % "set the interval to output", - (clipp::option("-t", "--timeout") & clipp::value("run time, default nearly infinite", MainConfig::run_time)) % "set the total simpling time"); - - auto SubOption = (clipp::option("-U", "--user-stack-only").call([] - { StackCollectorList.back()->kstack = false; }) % - "only sample user stacks", - clipp::option("-K", "--kernel-stack-only").call([] - { StackCollectorList.back()->ustack = false; }) % - "only sample kernel stacks", - (clipp::option("-m", "--max-value") & clipp::value("max threshold of sampled value", IntTmp).call([] - { StackCollectorList.back()->max = IntTmp; })) % - "set the max threshold of sampled value", - (clipp::option("-n", "--min-value") & clipp::value("min threshold of sampled value", IntTmp).call([] - { StackCollectorList.back()->min = IntTmp; })) % - "set the min threshold of sampled value"); - - auto OnCpuOption = (clipp::option("on-cpu").call([] - { StackCollectorList.push_back(new OnCPUStackCollector()); }) % - "sample the call stacks of on-cpu processes") & - (clipp::option("-F", "--frequency") & clipp::value("sampling frequency", IntTmp).call([] - { static_cast(StackCollectorList.back())->setScale(IntTmp); }) % - "sampling at a set frequency", - SubOption); - - auto OffCpuOption = clipp::option("off-cpu").call([] - { StackCollectorList.push_back(new OffCPUStackCollector()); }) % - "sample the call stacks of off-cpu processes" & - SubOption; - - auto MemoryOption = clipp::option("mem").call([] - { StackCollectorList.push_back(new MemoryStackCollector()); }) % - "sample the memory usage of call stacks" & - SubOption; - - auto IOOption = clipp::option("io").call([] - { StackCollectorList.push_back(new IOStackCollector()); }) % - "sample the IO data volume of call stacks" & - ((clipp::option("--mod") & (clipp::option("count").call([] - { static_cast(StackCollectorList.back())->setScale(IOStackCollector::io_mod::COUNT); }) % - "Counting the number of I/O operations" | - clipp::option("ave").call([] - { static_cast(StackCollectorList.back())->setScale(IOStackCollector::io_mod::AVE); }) % - "Counting the ave of I/O operations" | - clipp::option("size").call([] - { static_cast(StackCollectorList.back())->setScale(IOStackCollector::io_mod::SIZE); }) % - "Counting the size of I/O operations")) % - "set the statistic mod", - SubOption); - - auto ReadaheadOption = clipp::option("ra").call([] - { StackCollectorList.push_back(new ReadaheadStackCollector()); }) % - "sample the readahead hit rate of call stacks" & - SubOption; - - auto StackCountOption = clipp::option("stackcount").call([] - { StackCollectorList.push_back(new StackCountStackCollector()); }) % - "sample the counts of calling stacks" & - (clipp::option("-S", "--String") & clipp::value("probe String", StrTmp).call([] - { static_cast(StackCollectorList.back())->setProbe(StrTmp); }) % - "sampling at a set probe string", - SubOption); - - auto cli = (MainOption, - clipp::option("-v", "--version").call([] - { std::cout << "verion 2.0\n\n"; }) % - "show version", - OnCpuOption, - OffCpuOption, - MemoryOption, - IOOption, - ReadaheadOption, - StackCountOption) % - "statistic call trace relate with some metrics"; - - if (!clipp::parse(argc, argv, cli)) - { - std::cout << clipp::make_man_page(cli, argv[0]) << '\n'; - return 0; - } - - uint64_t eventbuff = 1; - int child_exec_event_fd = eventfd(0, EFD_CLOEXEC); - CHECK_ERR(child_exec_event_fd < 0, "failed to create event fd"); - if (MainConfig::command.length()) - { - MainConfig::target_pid = fork(); - switch (MainConfig::target_pid) - { - case -1: - { - std::cout << "command create failed." << std::endl; - return -1; - } - case 0: - { - const auto bytes = read(child_exec_event_fd, &eventbuff, sizeof(eventbuff)); - CHECK_ERR(bytes < 0, "failed to read from fd %ld", bytes) - else CHECK_ERR(bytes != sizeof(eventbuff), "read unexpected size %ld", bytes); - printf("child exec %s\n", MainConfig::command.c_str()); - CHECK_ERR_EXIT(execl("/bin/bash", "bash", "-c", MainConfig::command.c_str(), NULL), "failed to execute child command"); - break; - } - default: - { - printf("create child %d\n", MainConfig::target_pid); - break; - } - } - } - - for (auto Item = StackCollectorList.begin(); Item != StackCollectorList.end();) - { - (*Item)->pid = MainConfig::target_pid; - if ((*Item)->load()) - { - goto err; - } - if ((*Item)->attach()) - { - goto err; - } - Item++; - continue; - err: - fprintf(stderr, "%s eBPF prog err\n", (*Item)->scale.Type); - (*Item)->detach(); - (*Item)->unload(); - Item = StackCollectorList.erase(Item); - } - - if (MainConfig::command.length()) - { - printf("wake up child\n"); - write(child_exec_event_fd, &eventbuff, sizeof(eventbuff)); - } - - // printf("display mode: %d\n", MainConfig::d_mode); - - for (; MainConfig::run_time > 0 && (MainConfig::target_pid < 0 || !kill(MainConfig::target_pid, 0)); MainConfig::run_time -= MainConfig::delay) - { - sleep(MainConfig::delay); - for (auto Item : StackCollectorList) - { - Item->detach(); - std::cout << std::string(*Item); - Item->attach(); - } - } - - atexit(endCollect); -} \ No newline at end of file From c1c8c0851907ef3d19e3ebd49afb6834acd7de4c Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Sat, 16 Mar 2024 08:18:16 +0000 Subject: [PATCH 12/55] update file header Signed-off-by: LiuLingze --- .../stack_analyzer/bpf/io.bpf.c | 2 +- .../stack_analyzer/bpf/mem.bpf.c | 2 +- .../stack_analyzer/bpf/off_cpu.bpf.c | 2 +- .../stack_analyzer/bpf/on_cpu.bpf.c | 2 +- .../stack_analyzer/bpf/probe.bpf.c | 2 +- .../stack_analyzer/bpf/readahead.bpf.c | 2 +- .../stack_analyzer/bpf/template.bpf.c | 17 +++++++++++++++++ .../include/bpf/eBPFStackCollector.h | 18 ++++++++++++++++++ .../stack_analyzer/include/bpf/io.h | 18 ++++++++++++++++++ .../stack_analyzer/include/bpf/mem.h | 18 ++++++++++++++++++ .../stack_analyzer/include/bpf/off_cpu.h | 18 ++++++++++++++++++ .../stack_analyzer/include/bpf/on_cpu.h | 18 ++++++++++++++++++ .../stack_analyzer/include/bpf/probe.h | 18 ++++++++++++++++++ .../stack_analyzer/include/bpf/readahead.h | 18 ++++++++++++++++++ .../stack_analyzer/include/bpf/template.h | 18 ++++++++++++++++++ .../stack_analyzer/include/sa_common.h | 2 +- .../stack_analyzer/include/sa_ebpf.h | 2 +- .../stack_analyzer/include/sa_user.h | 2 +- .../src/bpf/eBPFStackCollector.cpp | 18 ++++++++++++++++++ .../stack_analyzer/src/bpf/io.cpp | 17 +++++++++++++++++ .../stack_analyzer/src/bpf/mem.cpp | 18 ++++++++++++++++++ .../stack_analyzer/src/bpf/off_cpu.cpp | 18 ++++++++++++++++++ .../stack_analyzer/src/bpf/on_cpu.cpp | 18 ++++++++++++++++++ .../stack_analyzer/src/bpf/probe.cpp | 18 ++++++++++++++++++ .../stack_analyzer/src/bpf/readahead.cpp | 18 ++++++++++++++++++ .../stack_analyzer/src/bpf/template.cpp | 18 ++++++++++++++++++ .../stack_analyzer/src/main.cpp | 18 ++++++++++++++++++ 27 files changed, 331 insertions(+), 9 deletions(-) diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/io.bpf.c b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/io.bpf.c index 51aa98d47..629cf1744 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/io.bpf.c +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/io.bpf.c @@ -1,4 +1,4 @@ -// Copyright 2023 The LMP Authors. +// Copyright 2024 The LMP Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/mem.bpf.c b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/mem.bpf.c index 40c96a743..868f97e07 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/mem.bpf.c +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/mem.bpf.c @@ -1,4 +1,4 @@ -// Copyright 2023 The LMP Authors. +// Copyright 2024 The LMP Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/off_cpu.bpf.c b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/off_cpu.bpf.c index 7bdaf0527..356d8f898 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/off_cpu.bpf.c +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/off_cpu.bpf.c @@ -1,4 +1,4 @@ -// Copyright 2023 The LMP Authors. +// Copyright 2024 The LMP Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/on_cpu.bpf.c b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/on_cpu.bpf.c index 1b479dcf9..7db0a095a 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/on_cpu.bpf.c +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/on_cpu.bpf.c @@ -1,4 +1,4 @@ -// Copyright 2023 The LMP Authors. +// Copyright 2024 The LMP Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/probe.bpf.c b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/probe.bpf.c index 5796a2a81..392a9e2da 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/probe.bpf.c +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/probe.bpf.c @@ -1,4 +1,4 @@ -// Copyright 2023 The LMP Authors. +// Copyright 2024 The LMP Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/readahead.bpf.c b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/readahead.bpf.c index 6f20da8c9..cdd8e1455 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/readahead.bpf.c +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/readahead.bpf.c @@ -1,4 +1,4 @@ -// Copyright 2023 The LMP Authors. +// Copyright 2024 The LMP Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/template.bpf.c b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/template.bpf.c index 05afde659..18c88c7ee 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/template.bpf.c +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/template.bpf.c @@ -1,3 +1,20 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// 内核态bpf程序的模板代码 #include "vmlinux.h" #include diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/eBPFStackCollector.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/eBPFStackCollector.h index ce231e819..137eb723a 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/eBPFStackCollector.h +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/eBPFStackCollector.h @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// 包装用于采集调用栈数据的eBPF程序,声明接口、通用成员和一些辅助结构 + #ifndef _SA_STACK_COLLECTOR_H__ #define _SA_STACK_COLLECTOR_H__ diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/io.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/io.h index bdcb68196..9370d5f0c 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/io.h +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/io.h @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// io ebpf程序的包装类,声明接口和一些自定义方法 + #ifndef _SA_IO_H__ #define _SA_IO_H__ diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/mem.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/mem.h index ae6dbf309..862f44122 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/mem.h +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/mem.h @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// mem ebpf程序的包装类,声明接口和一些自定义方法 + #ifndef _SA_MEMORY_H__ #define _SA_MEMORY_H__ diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/off_cpu.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/off_cpu.h index 95765ee3d..f9fb15e0e 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/off_cpu.h +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/off_cpu.h @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// off cpu ebpf程序的包装类,声明接口和一些自定义方法 + #ifndef _SA_OFF_CPU_H__ #define _SA_OFF_CPU_H__ diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/on_cpu.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/on_cpu.h index 015f8b8c7..9fd155035 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/on_cpu.h +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/on_cpu.h @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// on cpu ebpf程序的包装类,声明接口和一些自定义方法 + #ifndef _SA_ON_CPU_H__ #define _SA_ON_CPU_H__ diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/probe.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/probe.h index ca15e3108..60d24f7a4 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/probe.h +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/probe.h @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// probe ebpf程序的包装类,声明接口和一些自定义方法 + #include "bpf/eBPFStackCollector.h" #include "probe.skel.h" diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/readahead.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/readahead.h index 034df9fdd..5a6f6f23f 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/readahead.h +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/readahead.h @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// readahead ebpf程序的包装类,声明接口和一些自定义方法 + #ifndef _SA_READAHEAD_H__ #define _SA_READAHEAD_H__ diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/template.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/template.h index ae8516fec..2cb4a7509 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/template.h +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/template.h @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// ebpf程序的包装类的模板,声明接口和一些自定义方法,以及辅助结构 + #ifndef _TEMPLATE_H__ #define _TEMPLATE_H__ diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_common.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_common.h index 5735de509..d85564d5e 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_common.h +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_common.h @@ -1,4 +1,4 @@ -// Copyright 2023 The LMP Authors. +// Copyright 2024 The LMP Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_ebpf.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_ebpf.h index accbcba88..1dc55d83c 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_ebpf.h +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_ebpf.h @@ -1,4 +1,4 @@ -// Copyright 2023 The LMP Authors. +// Copyright 2024 The LMP Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_user.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_user.h index cee3b9c19..16efa7119 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_user.h +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_user.h @@ -1,4 +1,4 @@ -// Copyright 2023 The LMP Authors. +// Copyright 2024 The LMP Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/eBPFStackCollector.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/eBPFStackCollector.cpp index ea8284840..18f1ff32f 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/eBPFStackCollector.cpp +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/eBPFStackCollector.cpp @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// 包装用于采集调用栈数据的eBPF程序,规定一些抽象接口和通用变量 + #include "bpf/eBPFStackCollector.h" #include "sa_user.h" #include "dt_symbol.h" diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/io.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/io.cpp index b6284394b..77142738e 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/io.cpp +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/io.cpp @@ -1,3 +1,20 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// io ebpf程序的包装类,实现接口和一些自定义方法 #include "bpf/io.h" diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/mem.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/mem.cpp index b26a7bc23..90adc7461 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/mem.cpp +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/mem.cpp @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// mem ebpf程序的包装类,实现接口和一些自定义方法 + #include "bpf/mem.h" double MemoryStackCollector::count_value(void *d) diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/off_cpu.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/off_cpu.cpp index 589f839fd..f3bb2f7a6 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/off_cpu.cpp +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/off_cpu.cpp @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// off cpu ebpf程序的包装类,实现接口和一些自定义方法 + #include "bpf/off_cpu.h" OffCPUStackCollector::OffCPUStackCollector() diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/on_cpu.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/on_cpu.cpp index 587395aa7..1dd3d2db9 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/on_cpu.cpp +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/on_cpu.cpp @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// on cpu ebpf程序的包装类,实现接口和一些自定义方法 + #include "bpf/on_cpu.h" #include #include diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/probe.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/probe.cpp index e3407553e..778fec1a6 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/probe.cpp +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/probe.cpp @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: GaoYixiang +// +// probe ebpf 程序的包装类,实现接口和一些自定义方法 + #include "bpf/probe.h" double StackCountStackCollector::count_value(void *data) { diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/readahead.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/readahead.cpp index e3c09bf09..ee1b58ed8 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/readahead.cpp +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/readahead.cpp @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// readahead ebpf程序的包装类,实现接口和一些自定义方法 + #include "bpf/readahead.h" double ReadaheadStackCollector::count_value(void *data) diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/template.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/template.cpp index 10f0ca216..33acf521e 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/template.cpp +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/template.cpp @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// ebpf程序包装类的模板,实现接口和一些自定义方法 + #include "bpf/template.h" // ========== implement virtual func ========== diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/main.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/main.cpp index 7cc136abf..67f0df23d 100644 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/main.cpp +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/main.cpp @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// 主函数,负责参数解析,管理被监控命令对应的进程,数据输出 + #include #include From 739e529cfda3e9463813ecfdfd03493079f7734b Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Sat, 16 Mar 2024 12:44:37 +0000 Subject: [PATCH 13/55] Achieve code consistency Signed-off-by: LiuLingze --- .gitignore | 3 +- .../system_diagnosis/stack_analyzer/bpf | 1 + .../system_diagnosis/stack_analyzer/include | 1 + .../include/bpf/eBPFStackCollector.h | 143 - .../stack_analyzer/include/clipp.h | 7022 ----------------- .../stack_analyzer/include/sa_common.h | 39 - .../stack_analyzer/include/sa_ebpf.h | 80 - .../stack_analyzer/include/sa_user.h | 54 - .../stack_analyzer/include/task.h | 69 - .../system_diagnosis/stack_analyzer/src | 1 + .../src/bpf/eBPFStackCollector.cpp | 236 - eBPF_Supermarket/Stack_Analyser/Makefile | 36 +- .../Stack_Analyser}/bpf/io.bpf.c | 0 .../Stack_Analyser}/bpf/mem.bpf.c | 0 .../Stack_Analyser}/bpf/off_cpu.bpf.c | 0 .../Stack_Analyser}/bpf/on_cpu.bpf.c | 0 .../Stack_Analyser}/bpf/probe.bpf.c | 0 .../Stack_Analyser}/bpf/readahead.bpf.c | 0 .../Stack_Analyser}/bpf/template.bpf.c | 0 .../include/bpf/IOStackCollector.h | 41 - .../include/bpf/MemoryStackCollector.h | 90 - .../include/bpf/OffCPUStackCollector.h | 23 - .../include/bpf/OnCPUStackCollector.h | 32 - .../include/bpf/ProbeStackCollector.h | 22 - .../include/bpf/ReadaheadStackCollector.h | 32 - .../include/bpf/TemplateClass.h | 31 - .../include/bpf/eBPFStackCollector.h | 20 +- .../Stack_Analyser}/include/bpf/io.h | 0 .../Stack_Analyser}/include/bpf/mem.h | 0 .../Stack_Analyser}/include/bpf/off_cpu.h | 0 .../Stack_Analyser}/include/bpf/on_cpu.h | 0 .../Stack_Analyser}/include/bpf/probe.h | 0 .../Stack_Analyser}/include/bpf/readahead.h | 0 .../Stack_Analyser}/include/bpf/template.h | 0 .../Stack_Analyser}/include/dt_elf.h | 0 .../Stack_Analyser}/include/dt_symbol.h | 0 .../Stack_Analyser/include/elf.hpp | 25 - .../Stack_Analyser/include/sa_common.h | 2 +- .../Stack_Analyser/include/sa_ebpf.h | 2 +- .../Stack_Analyser/include/sa_user.h | 2 +- .../Stack_Analyser/include/symbol.h | 178 - eBPF_Supermarket/Stack_Analyser/main.cpp | 200 - eBPF_Supermarket/Stack_Analyser/new_bpf.sh | 14 +- .../src/bpf/IOStackCollector.cpp | 55 - .../src/bpf/MemoryStackCollector.cpp | 66 - .../src/bpf/OffCPUStackCollector.cpp | 33 - .../src/bpf/OnCPUStackCollector.cpp | 124 - .../src/bpf/ProbeStackCollector.cpp | 44 - .../src/bpf/ReadaheadStackCollector.cpp | 39 - .../Stack_Analyser/src/bpf/TemplateClass.cpp | 26 - .../src/bpf/eBPFStackCollector.cpp | 20 +- .../Stack_Analyser}/src/bpf/io.cpp | 0 .../Stack_Analyser/src/bpf/io_count.bpf.c | 94 - .../Stack_Analyser}/src/bpf/mem.cpp | 0 .../Stack_Analyser/src/bpf/mem_count.bpf.c | 222 - .../Stack_Analyser}/src/bpf/off_cpu.cpp | 0 .../src/bpf/off_cpu_count.bpf.c | 85 - .../Stack_Analyser}/src/bpf/on_cpu.cpp | 0 .../Stack_Analyser/src/bpf/on_cpu_count.bpf.c | 73 - .../Stack_Analyser/src/bpf/pre_count.bpf.c | 131 - .../Stack_Analyser}/src/bpf/probe.cpp | 0 .../Stack_Analyser}/src/bpf/readahead.cpp | 0 .../Stack_Analyser/src/bpf/stack_count.bpf.c | 85 - .../Stack_Analyser/src/bpf/template.bpf.c | 14 - .../Stack_Analyser}/src/bpf/template.cpp | 0 .../Stack_Analyser}/src/dt_elf.cpp | 0 .../Stack_Analyser}/src/dt_symbol.cpp | 0 eBPF_Supermarket/Stack_Analyser/src/elf.cc | 625 -- .../Stack_Analyser}/src/main.cpp | 0 eBPF_Supermarket/Stack_Analyser/src/symbol.cc | 563 -- 70 files changed, 70 insertions(+), 10628 deletions(-) create mode 120000 MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf create mode 120000 MagicEyes/src/backend/system_diagnosis/stack_analyzer/include delete mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/eBPFStackCollector.h delete mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/clipp.h delete mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_common.h delete mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_ebpf.h delete mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_user.h delete mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/task.h create mode 120000 MagicEyes/src/backend/system_diagnosis/stack_analyzer/src delete mode 100644 MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/eBPFStackCollector.cpp rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/bpf/io.bpf.c (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/bpf/mem.bpf.c (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/bpf/off_cpu.bpf.c (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/bpf/on_cpu.bpf.c (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/bpf/probe.bpf.c (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/bpf/readahead.bpf.c (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/bpf/template.bpf.c (100%) delete mode 100644 eBPF_Supermarket/Stack_Analyser/include/bpf/IOStackCollector.h delete mode 100644 eBPF_Supermarket/Stack_Analyser/include/bpf/MemoryStackCollector.h delete mode 100644 eBPF_Supermarket/Stack_Analyser/include/bpf/OffCPUStackCollector.h delete mode 100644 eBPF_Supermarket/Stack_Analyser/include/bpf/OnCPUStackCollector.h delete mode 100644 eBPF_Supermarket/Stack_Analyser/include/bpf/ProbeStackCollector.h delete mode 100644 eBPF_Supermarket/Stack_Analyser/include/bpf/ReadaheadStackCollector.h delete mode 100644 eBPF_Supermarket/Stack_Analyser/include/bpf/TemplateClass.h rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/include/bpf/io.h (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/include/bpf/mem.h (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/include/bpf/off_cpu.h (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/include/bpf/on_cpu.h (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/include/bpf/probe.h (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/include/bpf/readahead.h (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/include/bpf/template.h (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/include/dt_elf.h (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/include/dt_symbol.h (100%) delete mode 100644 eBPF_Supermarket/Stack_Analyser/include/elf.hpp delete mode 100644 eBPF_Supermarket/Stack_Analyser/include/symbol.h delete mode 100644 eBPF_Supermarket/Stack_Analyser/main.cpp delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/IOStackCollector.cpp delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/MemoryStackCollector.cpp delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/OffCPUStackCollector.cpp delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/OnCPUStackCollector.cpp delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/ProbeStackCollector.cpp delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/ReadaheadStackCollector.cpp delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/TemplateClass.cpp rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/src/bpf/io.cpp (100%) delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/io_count.bpf.c rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/src/bpf/mem.cpp (100%) delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/mem_count.bpf.c rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/src/bpf/off_cpu.cpp (100%) delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/off_cpu_count.bpf.c rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/src/bpf/on_cpu.cpp (100%) delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/on_cpu_count.bpf.c delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/pre_count.bpf.c rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/src/bpf/probe.cpp (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/src/bpf/readahead.cpp (100%) delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/stack_count.bpf.c delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/bpf/template.bpf.c rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/src/bpf/template.cpp (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/src/dt_elf.cpp (100%) rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/src/dt_symbol.cpp (100%) delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/elf.cc rename {MagicEyes/src/backend/system_diagnosis/stack_analyzer => eBPF_Supermarket/Stack_Analyser}/src/main.cpp (100%) delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/symbol.cc diff --git a/.gitignore b/.gitignore index 7152a7e3a..a3f27e445 100644 --- a/.gitignore +++ b/.gitignore @@ -77,4 +77,5 @@ eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/proc_image # Stack_Analyser eBPF_Supermarket/Stack_Analyser/stack_analyzer -eBPF_Supermarket/Stack_Analyser/exporter/exporter \ No newline at end of file +eBPF_Supermarket/Stack_Analyser/exporter/exporter +eBPF_Supermarket/Stack_Analyser/bpf_skel \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf new file mode 120000 index 000000000..1d246dce4 --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf @@ -0,0 +1 @@ +/home/a/Project/lmp/eBPF_Supermarket/Stack_Analyser/bpf/ \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include new file mode 120000 index 000000000..bd48a5e4f --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include @@ -0,0 +1 @@ +/home/a/Project/lmp/eBPF_Supermarket/Stack_Analyser/include/ \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/eBPFStackCollector.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/eBPFStackCollector.h deleted file mode 100644 index 137eb723a..000000000 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/eBPFStackCollector.h +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2024 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 包装用于采集调用栈数据的eBPF程序,声明接口、通用成员和一些辅助结构 - -#ifndef _SA_STACK_COLLECTOR_H__ -#define _SA_STACK_COLLECTOR_H__ - -#include -#include -#include -#include -#include "sa_user.h" - -struct Scale -{ - const char *Type, *Unit; - int64_t Period; -}; - -/// @brief count类,主要是为了重载比较运算,便于自动排序 -struct CountItem -{ - psid k; - double v; - CountItem(psid k, double v) : k(k), v(v){}; - - /// @brief count对象的大小取决于val的大小 - /// @param b 要比较的对象 - /// @return 小于b则为真,否则为假 - friend bool operator<(const CountItem a, const CountItem b); -}; - -class StackCollector -{ -protected: - struct bpf_object *obj = NULL; - - // 默认显示计数的变化情况,即每次输出数据后清除计数 - bool showDelta = true; - -public: - Scale scale = {0}; - - int pid = -1; // 用于设置ebpf程序跟踪的pid - int err = 0; // 用于保存错误代码 - - bool ustack = true; // 是否跟踪用户栈 - bool kstack = true; // 是否跟踪内核栈 - uint64_t min = 0; - uint64_t max = __UINT64_MAX__; // 设置采集指标最大值,最小值 - - int self_pid = -1; - -protected: - std::vector *sortedCountList(void); - - /// @brief 将缓冲区的数据解析为特定值 - /// @param 无 - /// @return 解析出的值 - virtual double count_value(void *data) = 0; - -public: - StackCollector(); - operator std::string(); - - /// @brief 负责ebpf程序的加载、参数设置和打开操作 - /// @param 无 - /// @return 成功则返回0,否则返回负数 - virtual int load(void) = 0; - - /// @brief 将ebpf程序挂载到跟踪点上 - /// @param 无 - /// @return 成功则返回0,否则返回负数 - virtual int attach(void) = 0; - - /// @brief 断开ebpf的跟踪点和处理函数间的连接 - /// @param 无 - virtual void detach(void) = 0; - - /// @brief 卸载ebpf程序 - /// @param 无 - virtual void unload(void) = 0; - -// 声明eBPF骨架 -#define declareEBPF(func) struct func##_bpf *skel = NULL; - -/// @brief 加载、初始化参数并打开指定类型的ebpf程序 -/// @param ... 一些ebpf程序全局变量初始化语句 -/// @note 失败会使上层函数返回-1 -#define StackProgLoadOpen(...) \ - { \ - skel = skel->open(NULL); \ - CHECK_ERR(!skel, "Fail to open BPF skeleton"); \ - skel->bss->min = min; \ - skel->bss->max = max; \ - skel->bss->u = ustack; \ - skel->bss->k = kstack; \ - skel->bss->self_pid = self_pid; \ - __VA_ARGS__; \ - err = skel->load(skel); \ - CHECK_ERR(err, "Fail to load BPF skeleton"); \ - obj = skel->obj; \ - } - -#define defaultAttach \ - { \ - err = skel->attach(skel); \ - CHECK_ERR(err, "Failed to attach BPF skeleton"); \ - } - -#define defaultDetach \ - { \ - if (skel) \ - { \ - skel->detach(skel); \ - } \ - } - -#define defaultUnload \ - { \ - if (skel) \ - { \ - skel->destroy(skel); \ - } \ - skel = NULL; \ - } -}; - -#endif \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/clipp.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/clipp.h deleted file mode 100644 index 757e74200..000000000 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/clipp.h +++ /dev/null @@ -1,7022 +0,0 @@ -/***************************************************************************** - * ___ _ _ ___ ___ - * | _|| | | | | _ \ _ \ CLIPP - command line interfaces for modern C++ - * | |_ | |_ | | | _/ _/ version 1.2.3 - * |___||___||_| |_| |_| https://github.com/muellan/clipp - * - * Licensed under the MIT License . - * Copyright (c) 2017-2018 André Müller - * - * --------------------------------------------------------------------------- - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - *****************************************************************************/ - -#ifndef AM_CLIPP_H__ -#define AM_CLIPP_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/*************************************************************************//** - * - * @brief primary namespace - * - *****************************************************************************/ -namespace clipp { - - - -/***************************************************************************** - * - * basic constants and datatype definitions - * - *****************************************************************************/ -using arg_index = int; - -using arg_string = std::string; -using doc_string = std::string; - -using arg_list = std::vector; - - - -/*************************************************************************//** - * - * @brief tristate - * - *****************************************************************************/ -enum class tri : char { no, yes, either }; - -inline constexpr bool operator == (tri t, bool b) noexcept { - return b ? t != tri::no : t != tri::yes; -} -inline constexpr bool operator == (bool b, tri t) noexcept { return (t == b); } -inline constexpr bool operator != (tri t, bool b) noexcept { return !(t == b); } -inline constexpr bool operator != (bool b, tri t) noexcept { return !(t == b); } - - - -/*************************************************************************//** - * - * @brief (start,size) index range - * - *****************************************************************************/ -class subrange { -public: - using size_type = arg_string::size_type; - - /** @brief default: no match */ - explicit constexpr - subrange() noexcept : - at_{arg_string::npos}, length_{0} - {} - - /** @brief match length & position within subject string */ - explicit constexpr - subrange(size_type pos, size_type len) noexcept : - at_{pos}, length_{len} - {} - - /** @brief position of the match within the subject string */ - constexpr size_type at() const noexcept { return at_; } - /** @brief length of the matching subsequence */ - constexpr size_type length() const noexcept { return length_; } - - /** @brief returns true, if query string is a prefix of the subject string */ - constexpr bool prefix() const noexcept { - return at_ == 0; - } - - /** @brief returns true, if query is a substring of the query string */ - constexpr explicit operator bool () const noexcept { - return at_ != arg_string::npos; - } - -private: - size_type at_; - size_type length_; -}; - - - -/*************************************************************************//** - * - * @brief match predicates - * - *****************************************************************************/ -using match_predicate = std::function; -using match_function = std::function; - - - - - - -/*************************************************************************//** - * - * @brief type traits (NOT FOR DIRECT USE IN CLIENT CODE!) - * no interface guarantees; might be changed or removed in the future - * - *****************************************************************************/ -namespace traits { - -/*************************************************************************//** - * - * @brief function (class) signature type trait - * - *****************************************************************************/ -template -constexpr auto -check_is_callable(int) -> decltype( - std::declval()(std::declval()...), - std::integral_constant::type>::value>{} ); - -template -constexpr auto -check_is_callable(long) -> std::false_type; - -template -constexpr auto -check_is_callable_without_arg(int) -> decltype( - std::declval()(), - std::integral_constant::type>::value>{} ); - -template -constexpr auto -check_is_callable_without_arg(long) -> std::false_type; - - - -template -constexpr auto -check_is_void_callable(int) -> decltype( - std::declval()(std::declval()...), std::true_type{}); - -template -constexpr auto -check_is_void_callable(long) -> std::false_type; - -template -constexpr auto -check_is_void_callable_without_arg(int) -> decltype( - std::declval()(), std::true_type{}); - -template -constexpr auto -check_is_void_callable_without_arg(long) -> std::false_type; - - - -template -struct is_callable; - - -template -struct is_callable : - decltype(check_is_callable(0)) -{}; - -template -struct is_callable : - decltype(check_is_callable_without_arg(0)) -{}; - - -template -struct is_callable : - decltype(check_is_void_callable(0)) -{}; - -template -struct is_callable : - decltype(check_is_void_callable_without_arg(0)) -{}; - - - -/*************************************************************************//** - * - * @brief input range type trait - * - *****************************************************************************/ -template -constexpr auto -check_is_input_range(int) -> decltype( - begin(std::declval()), end(std::declval()), - std::true_type{}); - -template -constexpr auto -check_is_input_range(char) -> decltype( - std::begin(std::declval()), std::end(std::declval()), - std::true_type{}); - -template -constexpr auto -check_is_input_range(long) -> std::false_type; - -template -struct is_input_range : - decltype(check_is_input_range(0)) -{}; - - - -/*************************************************************************//** - * - * @brief size() member type trait - * - *****************************************************************************/ -template -constexpr auto -check_has_size_getter(int) -> - decltype(std::declval().size(), std::true_type{}); - -template -constexpr auto -check_has_size_getter(long) -> std::false_type; - -template -struct has_size_getter : - decltype(check_has_size_getter(0)) -{}; - -} // namespace traits - - - - - - -/*************************************************************************//** - * - * @brief helpers (NOT FOR DIRECT USE IN CLIENT CODE!) - * no interface guarantees; might be changed or removed in the future - * - *****************************************************************************/ -namespace detail { - - -/*************************************************************************//** - * @brief forwards string to first non-whitespace char; - * std string -> unsigned conv yields max value, but we want 0; - * also checks for nullptr - *****************************************************************************/ -inline bool -fwd_to_unsigned_int(const char*& s) -{ - if(!s) return false; - for(; std::isspace(*s); ++s); - if(!s[0] || s[0] == '-') return false; - if(s[0] == '-') return false; - return true; -} - - -/*************************************************************************//** - * - * @brief value limits clamping - * - *****************************************************************************/ -template sizeof(T))> -struct limits_clamped { - static T from(const V& v) { - if(v >= V(std::numeric_limits::max())) { - return std::numeric_limits::max(); - } - if(v <= V(std::numeric_limits::lowest())) { - return std::numeric_limits::lowest(); - } - return T(v); - } -}; - -template -struct limits_clamped { - static T from(const V& v) { return T(v); } -}; - - -/*************************************************************************//** - * - * @brief returns value of v as a T, clamped at T's maximum - * - *****************************************************************************/ -template -inline T clamped_on_limits(const V& v) { - return limits_clamped::from(v); -} - - - - -/*************************************************************************//** - * - * @brief type conversion helpers - * - *****************************************************************************/ -template -struct make { - static inline T from(const char* s) { - if(!s) return false; - //a conversion from const char* to / must exist - return static_cast(s); - } -}; - -template<> -struct make { - static inline bool from(const char* s) { - if(!s) return false; - return static_cast(s); - } -}; - -template<> -struct make { - static inline unsigned char from(const char* s) { - if(!fwd_to_unsigned_int(s)) return (0); - return clamped_on_limits(std::strtoull(s,nullptr,10)); - } -}; - -template<> -struct make { - static inline unsigned short int from(const char* s) { - if(!fwd_to_unsigned_int(s)) return (0); - return clamped_on_limits(std::strtoull(s,nullptr,10)); - } -}; - -template<> -struct make { - static inline unsigned int from(const char* s) { - if(!fwd_to_unsigned_int(s)) return (0); - return clamped_on_limits(std::strtoull(s,nullptr,10)); - } -}; - -template<> -struct make { - static inline unsigned long int from(const char* s) { - if(!fwd_to_unsigned_int(s)) return (0); - return clamped_on_limits(std::strtoull(s,nullptr,10)); - } -}; - -template<> -struct make { - static inline unsigned long long int from(const char* s) { - if(!fwd_to_unsigned_int(s)) return (0); - return clamped_on_limits(std::strtoull(s,nullptr,10)); - } -}; - -template<> -struct make { - static inline char from(const char* s) { - //parse as single character? - const auto n = std::strlen(s); - if(n == 1) return s[0]; - //parse as integer - return clamped_on_limits(std::strtoll(s,nullptr,10)); - } -}; - -template<> -struct make { - static inline short int from(const char* s) { - return clamped_on_limits(std::strtoll(s,nullptr,10)); - } -}; - -template<> -struct make { - static inline int from(const char* s) { - return clamped_on_limits(std::strtoll(s,nullptr,10)); - } -}; - -template<> -struct make { - static inline long int from(const char* s) { - return clamped_on_limits(std::strtoll(s,nullptr,10)); - } -}; - -template<> -struct make { - static inline long long int from(const char* s) { - return (std::strtoll(s,nullptr,10)); - } -}; - -template<> -struct make { - static inline float from(const char* s) { - return (std::strtof(s,nullptr)); - } -}; - -template<> -struct make { - static inline double from(const char* s) { - return (std::strtod(s,nullptr)); - } -}; - -template<> -struct make { - static inline long double from(const char* s) { - return (std::strtold(s,nullptr)); - } -}; - -template<> -struct make { - static inline std::string from(const char* s) { - return std::string(s); - } -}; - - - -/*************************************************************************//** - * - * @brief assigns boolean constant to one or multiple target objects - * - *****************************************************************************/ -template -class assign_value -{ -public: - template - explicit constexpr - assign_value(T& target, X&& value) noexcept : - t_{std::addressof(target)}, v_{std::forward(value)} - {} - - void operator () () const { - if(t_) *t_ = v_; - } - -private: - T* t_; - V v_; -}; - - - -/*************************************************************************//** - * - * @brief flips bools - * - *****************************************************************************/ -class flip_bool -{ -public: - explicit constexpr - flip_bool(bool& target) noexcept : - b_{&target} - {} - - void operator () () const { - if(b_) *b_ = !*b_; - } - -private: - bool* b_; -}; - - - -/*************************************************************************//** - * - * @brief increments using operator ++ - * - *****************************************************************************/ -template -class increment -{ -public: - explicit constexpr - increment(T& target) noexcept : t_{std::addressof(target)} {} - - void operator () () const { - if(t_) ++(*t_); - } - -private: - T* t_; -}; - - - -/*************************************************************************//** - * - * @brief decrements using operator -- - * - *****************************************************************************/ -template -class decrement -{ -public: - explicit constexpr - decrement(T& target) noexcept : t_{std::addressof(target)} {} - - void operator () () const { - if(t_) --(*t_); - } - -private: - T* t_; -}; - - - -/*************************************************************************//** - * - * @brief increments by a fixed amount using operator += - * - *****************************************************************************/ -template -class increment_by -{ -public: - explicit constexpr - increment_by(T& target, T by) noexcept : - t_{std::addressof(target)}, by_{std::move(by)} - {} - - void operator () () const { - if(t_) (*t_) += by_; - } - -private: - T* t_; - T by_; -}; - - - - -/*************************************************************************//** - * - * @brief makes a value from a string and assigns it to an object - * - *****************************************************************************/ -template -class map_arg_to -{ -public: - explicit constexpr - map_arg_to(T& target) noexcept : t_{std::addressof(target)} {} - - void operator () (const char* s) const { - if(t_ && s) *t_ = detail::make::from(s); - } - -private: - T* t_; -}; - - -//------------------------------------------------------------------- -/** - * @brief specialization for vectors: append element - */ -template -class map_arg_to> -{ -public: - map_arg_to(std::vector& target): t_{std::addressof(target)} {} - - void operator () (const char* s) const { - if(t_ && s) t_->push_back(detail::make::from(s)); - } - -private: - std::vector* t_; -}; - - -//------------------------------------------------------------------- -/** - * @brief specialization for bools: - * set to true regardless of string content - */ -template<> -class map_arg_to -{ -public: - map_arg_to(bool& target): t_{&target} {} - - void operator () (const char* s) const { - if(t_ && s) *t_ = true; - } - -private: - bool* t_; -}; - - -} // namespace detail - - - - - - -/*************************************************************************//** - * - * @brief string matching and processing tools - * - *****************************************************************************/ - -namespace str { - - -/*************************************************************************//** - * - * @brief converts string to value of target type 'T' - * - *****************************************************************************/ -template -T make(const arg_string& s) -{ - return detail::make::from(s); -} - - - -/*************************************************************************//** - * - * @brief removes trailing whitespace from string - * - *****************************************************************************/ -template -inline void -trimr(std::basic_string& s) -{ - if(s.empty()) return; - - s.erase( - std::find_if_not(s.rbegin(), s.rend(), - [](char c) { return std::isspace(c);} ).base(), - s.end() ); -} - - -/*************************************************************************//** - * - * @brief removes leading whitespace from string - * - *****************************************************************************/ -template -inline void -triml(std::basic_string& s) -{ - if(s.empty()) return; - - s.erase( - s.begin(), - std::find_if_not(s.begin(), s.end(), - [](char c) { return std::isspace(c);}) - ); -} - - -/*************************************************************************//** - * - * @brief removes leading and trailing whitespace from string - * - *****************************************************************************/ -template -inline void -trim(std::basic_string& s) -{ - triml(s); - trimr(s); -} - - -/*************************************************************************//** - * - * @brief removes all whitespaces from string - * - *****************************************************************************/ -template -inline void -remove_ws(std::basic_string& s) -{ - if(s.empty()) return; - - s.erase(std::remove_if(s.begin(), s.end(), - [](char c) { return std::isspace(c); }), - s.end() ); -} - - -/*************************************************************************//** - * - * @brief returns true, if the 'prefix' argument - * is a prefix of the 'subject' argument - * - *****************************************************************************/ -template -inline bool -has_prefix(const std::basic_string& subject, - const std::basic_string& prefix) -{ - if(prefix.size() > subject.size()) return false; - return subject.find(prefix) == 0; -} - - -/*************************************************************************//** - * - * @brief returns true, if the 'postfix' argument - * is a postfix of the 'subject' argument - * - *****************************************************************************/ -template -inline bool -has_postfix(const std::basic_string& subject, - const std::basic_string& postfix) -{ - if(postfix.size() > subject.size()) return false; - return (subject.size() - postfix.size()) == subject.find(postfix); -} - - - -/*************************************************************************//** -* -* @brief returns longest common prefix of several -* sequential random access containers -* -* @details InputRange require begin and end (member functions or overloads) -* the elements of InputRange require a size() member -* -*****************************************************************************/ -template -auto -longest_common_prefix(const InputRange& strs) - -> typename std::decay::type -{ - static_assert(traits::is_input_range(), - "parameter must satisfy the InputRange concept"); - - static_assert(traits::has_size_getter< - typename std::decay::type>(), - "elements of input range must have a ::size() member function"); - - using std::begin; - using std::end; - - using item_t = typename std::decay::type; - using str_size_t = typename std::decaysize())>::type; - - const auto n = size_t(distance(begin(strs), end(strs))); - if(n < 1) return item_t(""); - if(n == 1) return *begin(strs); - - //length of shortest string - auto m = std::min_element(begin(strs), end(strs), - [](const item_t& a, const item_t& b) { - return a.size() < b.size(); })->size(); - - //check each character until we find a mismatch - for(str_size_t i = 0; i < m; ++i) { - for(str_size_t j = 1; j < n; ++j) { - if(strs[j][i] != strs[j-1][i]) - return strs[0].substr(0, i); - } - } - return strs[0].substr(0, m); -} - - - -/*************************************************************************//** - * - * @brief returns longest substring range that could be found in 'arg' - * - * @param arg string to be searched in - * @param substrings range of candidate substrings - * - *****************************************************************************/ -template -subrange -longest_substring_match(const std::basic_string& arg, - const InputRange& substrings) -{ - using string_t = std::basic_string; - - static_assert(traits::is_input_range(), - "parameter must satisfy the InputRange concept"); - - static_assert(std::is_same::type>(), - "substrings must have same type as 'arg'"); - - auto i = string_t::npos; - auto n = string_t::size_type(0); - for(const auto& s : substrings) { - auto j = arg.find(s); - if(j != string_t::npos && s.size() > n) { - i = j; - n = s.size(); - } - } - return subrange{i,n}; -} - - - -/*************************************************************************//** - * - * @brief returns longest prefix range that could be found in 'arg' - * - * @param arg string to be searched in - * @param prefixes range of candidate prefix strings - * - *****************************************************************************/ -template -subrange -longest_prefix_match(const std::basic_string& arg, - const InputRange& prefixes) -{ - using string_t = std::basic_string; - using s_size_t = typename string_t::size_type; - - static_assert(traits::is_input_range(), - "parameter must satisfy the InputRange concept"); - - static_assert(std::is_same::type>(), - "prefixes must have same type as 'arg'"); - - auto i = string_t::npos; - auto n = s_size_t(0); - for(const auto& s : prefixes) { - auto j = arg.find(s); - if(j == 0 && s.size() > n) { - i = 0; - n = s.size(); - } - } - return subrange{i,n}; -} - - - -/*************************************************************************//** - * - * @brief returns the first occurrence of 'query' within 'subject' - * - *****************************************************************************/ -template -inline subrange -substring_match(const std::basic_string& subject, - const std::basic_string& query) -{ - if(subject.empty() && query.empty()) return subrange(0,0); - if(subject.empty() || query.empty()) return subrange{}; - auto i = subject.find(query); - if(i == std::basic_string::npos) return subrange{}; - return subrange{i,query.size()}; -} - - - -/*************************************************************************//** - * - * @brief returns first substring match (pos,len) within the input string - * that represents a number - * (with at maximum one decimal point and digit separators) - * - *****************************************************************************/ -template -subrange -first_number_match(std::basic_string s, - C digitSeparator = C(','), - C decimalPoint = C('.'), - C exponential = C('e')) -{ - using string_t = std::basic_string; - - str::trim(s); - if(s.empty()) return subrange{}; - - auto i = s.find_first_of("0123456789+-"); - if(i == string_t::npos) { - i = s.find(decimalPoint); - if(i == string_t::npos) return subrange{}; - } - - bool point = false; - bool sep = false; - auto exp = string_t::npos; - auto j = i + 1; - for(; j < s.size(); ++j) { - if(s[j] == digitSeparator) { - if(!sep) sep = true; else break; - } - else { - sep = false; - if(s[j] == decimalPoint) { - //only one decimal point before exponent allowed - if(!point && exp == string_t::npos) point = true; else break; - } - else if(std::tolower(s[j]) == std::tolower(exponential)) { - //only one exponent separator allowed - if(exp == string_t::npos) exp = j; else break; - } - else if(exp != string_t::npos && (exp+1) == j) { - //only sign or digit after exponent separator - if(s[j] != '+' && s[j] != '-' && !std::isdigit(s[j])) break; - } - else if(!std::isdigit(s[j])) { - break; - } - } - } - - //if length == 1 then must be a digit - if(j-i == 1 && !std::isdigit(s[i])) return subrange{}; - - return subrange{i,j-i}; -} - - - -/*************************************************************************//** - * - * @brief returns first substring match (pos,len) - * that represents an integer (with optional digit separators) - * - *****************************************************************************/ -template -subrange -first_integer_match(std::basic_string s, - C digitSeparator = C(',')) -{ - using string_t = std::basic_string; - - str::trim(s); - if(s.empty()) return subrange{}; - - auto i = s.find_first_of("0123456789+-"); - if(i == string_t::npos) return subrange{}; - - bool sep = false; - auto j = i + 1; - for(; j < s.size(); ++j) { - if(s[j] == digitSeparator) { - if(!sep) sep = true; else break; - } - else { - sep = false; - if(!std::isdigit(s[j])) break; - } - } - - //if length == 1 then must be a digit - if(j-i == 1 && !std::isdigit(s[i])) return subrange{}; - - return subrange{i,j-i}; -} - - - -/*************************************************************************//** - * - * @brief returns true if candidate string represents a number - * - *****************************************************************************/ -template -bool represents_number(const std::basic_string& candidate, - C digitSeparator = C(','), - C decimalPoint = C('.'), - C exponential = C('e')) -{ - const auto match = str::first_number_match(candidate, digitSeparator, - decimalPoint, exponential); - - return (match && match.length() == candidate.size()); -} - - - -/*************************************************************************//** - * - * @brief returns true if candidate string represents an integer - * - *****************************************************************************/ -template -bool represents_integer(const std::basic_string& candidate, - C digitSeparator = C(',')) -{ - const auto match = str::first_integer_match(candidate, digitSeparator); - return (match && match.length() == candidate.size()); -} - -} // namespace str - - - - - - -/*************************************************************************//** - * - * @brief makes function object with a const char* parameter - * that assigns a value to a ref-captured object - * - *****************************************************************************/ -template -inline detail::assign_value -set(T& target, V value) { - return detail::assign_value{target, std::move(value)}; -} - - - -/*************************************************************************//** - * - * @brief makes parameter-less function object - * that assigns value(s) to a ref-captured object; - * value(s) are obtained by converting the const char* argument to - * the captured object types; - * bools are always set to true if the argument is not nullptr - * - *****************************************************************************/ -template -inline detail::map_arg_to -set(T& target) { - return detail::map_arg_to{target}; -} - - - -/*************************************************************************//** - * - * @brief makes function object that sets a bool to true - * - *****************************************************************************/ -inline detail::assign_value -set(bool& target) { - return detail::assign_value{target,true}; -} - -/*************************************************************************//** - * - * @brief makes function object that sets a bool to false - * - *****************************************************************************/ -inline detail::assign_value -unset(bool& target) { - return detail::assign_value{target,false}; -} - -/*************************************************************************//** - * - * @brief makes function object that flips the value of a ref-captured bool - * - *****************************************************************************/ -inline detail::flip_bool -flip(bool& b) { - return detail::flip_bool(b); -} - - - - - -/*************************************************************************//** - * - * @brief makes function object that increments using operator ++ - * - *****************************************************************************/ -template -inline detail::increment -increment(T& target) { - return detail::increment{target}; -} - -/*************************************************************************//** - * - * @brief makes function object that decrements using operator -- - * - *****************************************************************************/ -template -inline detail::increment_by -increment(T& target, T by) { - return detail::increment_by{target, std::move(by)}; -} - -/*************************************************************************//** - * - * @brief makes function object that increments by a fixed amount using operator += - * - *****************************************************************************/ -template -inline detail::decrement -decrement(T& target) { - return detail::decrement{target}; -} - - - - - - -/*************************************************************************//** - * - * @brief helpers (NOT FOR DIRECT USE IN CLIENT CODE!) - * - *****************************************************************************/ -namespace detail { - - -/*************************************************************************//** - * - * @brief mixin that provides action definition and execution - * - *****************************************************************************/ -template -class action_provider -{ -private: - //--------------------------------------------------------------- - using simple_action = std::function; - using arg_action = std::function; - using index_action = std::function; - - //----------------------------------------------------- - class simple_action_adapter { - public: - simple_action_adapter() = default; - simple_action_adapter(const simple_action& a): action_(a) {} - simple_action_adapter(simple_action&& a): action_(std::move(a)) {} - void operator() (const char*) const { action_(); } - void operator() (int) const { action_(); } - private: - simple_action action_; - }; - - -public: - //--------------------------------------------------------------- - /** @brief adds an action that has an operator() that is callable - * with a 'const char*' argument */ - Derived& - call(arg_action a) { - argActions_.push_back(std::move(a)); - return *static_cast(this); - } - - /** @brief adds an action that has an operator()() */ - Derived& - call(simple_action a) { - argActions_.push_back(simple_action_adapter(std::move(a))); - return *static_cast(this); - } - - /** @brief adds an action that has an operator() that is callable - * with a 'const char*' argument */ - Derived& operator () (arg_action a) { return call(std::move(a)); } - - /** @brief adds an action that has an operator()() */ - Derived& operator () (simple_action a) { return call(std::move(a)); } - - - //--------------------------------------------------------------- - /** @brief adds an action that will set the value of 't' from - * a 'const char*' arg */ - template - Derived& - set(Target& t) { - static_assert(!std::is_pointer::value, - "parameter target type must not be a pointer"); - - return call(clipp::set(t)); - } - - /** @brief adds an action that will set the value of 't' to 'v' */ - template - Derived& - set(Target& t, Value&& v) { - return call(clipp::set(t, std::forward(v))); - } - - - //--------------------------------------------------------------- - /** @brief adds an action that will be called if a parameter - * matches an argument for the 2nd, 3rd, 4th, ... time - */ - Derived& - if_repeated(simple_action a) { - repeatActions_.push_back(simple_action_adapter{std::move(a)}); - return *static_cast(this); - } - /** @brief adds an action that will be called with the argument's - * index if a parameter matches an argument for - * the 2nd, 3rd, 4th, ... time - */ - Derived& - if_repeated(index_action a) { - repeatActions_.push_back(std::move(a)); - return *static_cast(this); - } - - - //--------------------------------------------------------------- - /** @brief adds an action that will be called if a required parameter - * is missing - */ - Derived& - if_missing(simple_action a) { - missingActions_.push_back(simple_action_adapter{std::move(a)}); - return *static_cast(this); - } - /** @brief adds an action that will be called if a required parameter - * is missing; the action will get called with the index of - * the command line argument where the missing event occurred first - */ - Derived& - if_missing(index_action a) { - missingActions_.push_back(std::move(a)); - return *static_cast(this); - } - - - //--------------------------------------------------------------- - /** @brief adds an action that will be called if a parameter - * was matched, but was unreachable in the current scope - */ - Derived& - if_blocked(simple_action a) { - blockedActions_.push_back(simple_action_adapter{std::move(a)}); - return *static_cast(this); - } - /** @brief adds an action that will be called if a parameter - * was matched, but was unreachable in the current scope; - * the action will be called with the index of - * the command line argument where the problem occurred - */ - Derived& - if_blocked(index_action a) { - blockedActions_.push_back(std::move(a)); - return *static_cast(this); - } - - - //--------------------------------------------------------------- - /** @brief adds an action that will be called if a parameter match - * was in conflict with a different alternative parameter - */ - Derived& - if_conflicted(simple_action a) { - conflictActions_.push_back(simple_action_adapter{std::move(a)}); - return *static_cast(this); - } - /** @brief adds an action that will be called if a parameter match - * was in conflict with a different alternative parameter; - * the action will be called with the index of - * the command line argument where the problem occurred - */ - Derived& - if_conflicted(index_action a) { - conflictActions_.push_back(std::move(a)); - return *static_cast(this); - } - - - //--------------------------------------------------------------- - /** @brief adds targets = either objects whose values should be - * set by command line arguments or actions that should - * be called in case of a match */ - template - Derived& - target(T&& t, Ts&&... ts) { - target(std::forward(t)); - target(std::forward(ts)...); - return *static_cast(this); - } - - /** @brief adds action that should be called in case of a match */ - template::type>() && - (traits::is_callable() || - traits::is_callable() ) - >::type> - Derived& - target(T&& t) { - call(std::forward(t)); - return *static_cast(this); - } - - /** @brief adds object whose value should be set by command line arguments - */ - template::type>() || - (!traits::is_callable() && - !traits::is_callable() ) - >::type> - Derived& - target(T& t) { - set(t); - return *static_cast(this); - } - - //TODO remove ugly empty param list overload - Derived& - target() { - return *static_cast(this); - } - - - //--------------------------------------------------------------- - /** @brief adds target, see member function 'target' */ - template - inline friend Derived& - operator << (Target&& t, Derived& p) { - p.target(std::forward(t)); - return p; - } - /** @brief adds target, see member function 'target' */ - template - inline friend Derived&& - operator << (Target&& t, Derived&& p) { - p.target(std::forward(t)); - return std::move(p); - } - - //----------------------------------------------------- - /** @brief adds target, see member function 'target' */ - template - inline friend Derived& - operator >> (Derived& p, Target&& t) { - p.target(std::forward(t)); - return p; - } - /** @brief adds target, see member function 'target' */ - template - inline friend Derived&& - operator >> (Derived&& p, Target&& t) { - p.target(std::forward(t)); - return std::move(p); - } - - - //--------------------------------------------------------------- - /** @brief executes all argument actions */ - void execute_actions(const arg_string& arg) const { - for(const auto& a : argActions_) { - a(arg.c_str()); - } - } - - /** @brief executes repeat actions */ - void notify_repeated(arg_index idx) const { - for(const auto& a : repeatActions_) a(idx); - } - /** @brief executes missing error actions */ - void notify_missing(arg_index idx) const { - for(const auto& a : missingActions_) a(idx); - } - /** @brief executes blocked error actions */ - void notify_blocked(arg_index idx) const { - for(const auto& a : blockedActions_) a(idx); - } - /** @brief executes conflict error actions */ - void notify_conflict(arg_index idx) const { - for(const auto& a : conflictActions_) a(idx); - } - -private: - //--------------------------------------------------------------- - std::vector argActions_; - std::vector repeatActions_; - std::vector missingActions_; - std::vector blockedActions_; - std::vector conflictActions_; -}; - - - - - - -/*************************************************************************//** - * - * @brief mixin that provides basic common settings of parameters and groups - * - *****************************************************************************/ -template -class token -{ -public: - //--------------------------------------------------------------- - using doc_string = clipp::doc_string; - - - //--------------------------------------------------------------- - /** @brief returns documentation string */ - const doc_string& doc() const noexcept { - return doc_; - } - - /** @brief sets documentations string */ - Derived& doc(const doc_string& txt) { - doc_ = txt; - return *static_cast(this); - } - - /** @brief sets documentations string */ - Derived& doc(doc_string&& txt) { - doc_ = std::move(txt); - return *static_cast(this); - } - - - //--------------------------------------------------------------- - /** @brief returns if a group/parameter is repeatable */ - bool repeatable() const noexcept { - return repeatable_; - } - - /** @brief sets repeatability of group/parameter */ - Derived& repeatable(bool yes) noexcept { - repeatable_ = yes; - return *static_cast(this); - } - - - //--------------------------------------------------------------- - /** @brief returns if a group/parameter is blocking/positional */ - bool blocking() const noexcept { - return blocking_; - } - - /** @brief determines, if a group/parameter is blocking/positional */ - Derived& blocking(bool yes) noexcept { - blocking_ = yes; - return *static_cast(this); - } - - -private: - //--------------------------------------------------------------- - doc_string doc_; - bool repeatable_ = false; - bool blocking_ = false; -}; - - - - -/*************************************************************************//** - * - * @brief sets documentation strings on a token - * - *****************************************************************************/ -template -inline T& -operator % (doc_string docstr, token& p) -{ - return p.doc(std::move(docstr)); -} -//--------------------------------------------------------- -template -inline T&& -operator % (doc_string docstr, token&& p) -{ - return std::move(p.doc(std::move(docstr))); -} - -//--------------------------------------------------------- -template -inline T& -operator % (token& p, doc_string docstr) -{ - return p.doc(std::move(docstr)); -} -//--------------------------------------------------------- -template -inline T&& -operator % (token&& p, doc_string docstr) -{ - return std::move(p.doc(std::move(docstr))); -} - - - - -/*************************************************************************//** - * - * @brief sets documentation strings on a token - * - *****************************************************************************/ -template -inline T& -doc(doc_string docstr, token& p) -{ - return p.doc(std::move(docstr)); -} -//--------------------------------------------------------- -template -inline T&& -doc(doc_string docstr, token&& p) -{ - return std::move(p.doc(std::move(docstr))); -} - - - -} // namespace detail - - - -/*************************************************************************//** - * - * @brief contains parameter matching functions and function classes - * - *****************************************************************************/ -namespace match { - - -/*************************************************************************//** - * - * @brief predicate that is always true - * - *****************************************************************************/ -inline bool -any(const arg_string&) { return true; } - -/*************************************************************************//** - * - * @brief predicate that is always false - * - *****************************************************************************/ -inline bool -none(const arg_string&) { return false; } - - - -/*************************************************************************//** - * - * @brief predicate that returns true if the argument string is non-empty string - * - *****************************************************************************/ -inline bool -nonempty(const arg_string& s) { - return !s.empty(); -} - - - -/*************************************************************************//** - * - * @brief predicate that returns true if the argument is a non-empty - * string that consists only of alphanumeric characters - * - *****************************************************************************/ -inline bool -alphanumeric(const arg_string& s) { - if(s.empty()) return false; - return std::all_of(s.begin(), s.end(), [](char c) {return std::isalnum(c); }); -} - - - -/*************************************************************************//** - * - * @brief predicate that returns true if the argument is a non-empty - * string that consists only of alphabetic characters - * - *****************************************************************************/ -inline bool -alphabetic(const arg_string& s) { - return std::all_of(s.begin(), s.end(), [](char c) {return std::isalpha(c); }); -} - - - -/*************************************************************************//** - * - * @brief predicate that returns false if the argument string is - * equal to any string from the exclusion list - * - *****************************************************************************/ -class none_of -{ -public: - none_of(arg_list strs): - excluded_{std::move(strs)} - {} - - template - none_of(arg_string str, Strings&&... strs): - excluded_{std::move(str), std::forward(strs)...} - {} - - template - none_of(const char* str, Strings&&... strs): - excluded_{arg_string(str), std::forward(strs)...} - {} - - bool operator () (const arg_string& arg) const { - return (std::find(begin(excluded_), end(excluded_), arg) - == end(excluded_)); - } - -private: - arg_list excluded_; -}; - - - -/*************************************************************************//** - * - * @brief predicate that returns the first substring match within the input - * string that rmeepresents a number - * (with at maximum one decimal point and digit separators) - * - *****************************************************************************/ -class numbers -{ -public: - explicit - numbers(char decimalPoint = '.', - char digitSeparator = ' ', - char exponentSeparator = 'e') - : - decpoint_{decimalPoint}, separator_{digitSeparator}, - exp_{exponentSeparator} - {} - - subrange operator () (const arg_string& s) const { - return str::first_number_match(s, separator_, decpoint_, exp_); - } - -private: - char decpoint_; - char separator_; - char exp_; -}; - - - -/*************************************************************************//** - * - * @brief predicate that returns true if the input string represents an integer - * (with optional digit separators) - * - *****************************************************************************/ -class integers { -public: - explicit - integers(char digitSeparator = ' '): separator_{digitSeparator} {} - - subrange operator () (const arg_string& s) const { - return str::first_integer_match(s, separator_); - } - -private: - char separator_; -}; - - - -/*************************************************************************//** - * - * @brief predicate that returns true if the input string represents - * a non-negative integer (with optional digit separators) - * - *****************************************************************************/ -class positive_integers { -public: - explicit - positive_integers(char digitSeparator = ' '): separator_{digitSeparator} {} - - subrange operator () (const arg_string& s) const { - auto match = str::first_integer_match(s, separator_); - if(!match) return subrange{}; - if(s[match.at()] == '-') return subrange{}; - return match; - } - -private: - char separator_; -}; - - - -/*************************************************************************//** - * - * @brief predicate that returns true if the input string - * contains a given substring - * - *****************************************************************************/ -class substring -{ -public: - explicit - substring(arg_string str): str_{std::move(str)} {} - - subrange operator () (const arg_string& s) const { - return str::substring_match(s, str_); - } - -private: - arg_string str_; -}; - - - -/*************************************************************************//** - * - * @brief predicate that returns true if the input string starts - * with a given prefix - * - *****************************************************************************/ -class prefix { -public: - explicit - prefix(arg_string p): prefix_{std::move(p)} {} - - bool operator () (const arg_string& s) const { - return s.find(prefix_) == 0; - } - -private: - arg_string prefix_; -}; - - - -/*************************************************************************//** - * - * @brief predicate that returns true if the input string does not start - * with a given prefix - * - *****************************************************************************/ -class prefix_not { -public: - explicit - prefix_not(arg_string p): prefix_{std::move(p)} {} - - bool operator () (const arg_string& s) const { - return s.find(prefix_) != 0; - } - -private: - arg_string prefix_; -}; - - -/** @brief alias for prefix_not */ -using noprefix = prefix_not; - - - -/*************************************************************************//** - * - * @brief predicate that returns true if the length of the input string - * is wihtin a given interval - * - *****************************************************************************/ -class length { -public: - explicit - length(std::size_t exact): - min_{exact}, max_{exact} - {} - - explicit - length(std::size_t min, std::size_t max): - min_{min}, max_{max} - {} - - bool operator () (const arg_string& s) const { - return s.size() >= min_ && s.size() <= max_; - } - -private: - std::size_t min_; - std::size_t max_; -}; - - -/*************************************************************************//** - * - * @brief makes function object that returns true if the input string has a - * given minimum length - * - *****************************************************************************/ -inline length min_length(std::size_t min) -{ - return length{min, arg_string::npos-1}; -} - -/*************************************************************************//** - * - * @brief makes function object that returns true if the input string is - * not longer than a given maximum length - * - *****************************************************************************/ -inline length max_length(std::size_t max) -{ - return length{0, max}; -} - - -} // namespace match - - - - - -/*************************************************************************//** - * - * @brief command line parameter that can match one or many arguments. - * - *****************************************************************************/ -class parameter : - public detail::token, - public detail::action_provider -{ - /** @brief adapts a 'match_predicate' to the 'match_function' interface */ - class predicate_adapter { - public: - explicit - predicate_adapter(match_predicate pred): match_{std::move(pred)} {} - - subrange operator () (const arg_string& arg) const { - return match_(arg) ? subrange{0,arg.size()} : subrange{}; - } - - private: - match_predicate match_; - }; - -public: - //--------------------------------------------------------------- - /** @brief makes default parameter, that will match nothing */ - parameter(): - flags_{}, - matcher_{predicate_adapter{match::none}}, - label_{}, required_{false}, greedy_{false} - {} - - /** @brief makes "flag" parameter */ - template - explicit - parameter(arg_string str, Strings&&... strs): - flags_{}, - matcher_{predicate_adapter{match::none}}, - label_{}, required_{false}, greedy_{false} - { - add_flags(std::move(str), std::forward(strs)...); - } - - /** @brief makes "flag" parameter from range of strings */ - explicit - parameter(const arg_list& flaglist): - flags_{}, - matcher_{predicate_adapter{match::none}}, - label_{}, required_{false}, greedy_{false} - { - add_flags(flaglist); - } - - //----------------------------------------------------- - /** @brief makes "value" parameter with custom match predicate - * (= yes/no matcher) - */ - explicit - parameter(match_predicate filter): - flags_{}, - matcher_{predicate_adapter{std::move(filter)}}, - label_{}, required_{false}, greedy_{false} - {} - - /** @brief makes "value" parameter with custom match function - * (= partial matcher) - */ - explicit - parameter(match_function filter): - flags_{}, - matcher_{std::move(filter)}, - label_{}, required_{false}, greedy_{false} - {} - - - //--------------------------------------------------------------- - /** @brief returns if a parameter is required */ - bool - required() const noexcept { - return required_; - } - - /** @brief determines if a parameter is required */ - parameter& - required(bool yes) noexcept { - required_ = yes; - return *this; - } - - - //--------------------------------------------------------------- - /** @brief returns if a parameter should match greedily */ - bool - greedy() const noexcept { - return greedy_; - } - - /** @brief determines if a parameter should match greedily */ - parameter& - greedy(bool yes) noexcept { - greedy_ = yes; - return *this; - } - - - //--------------------------------------------------------------- - /** @brief returns parameter label; - * will be used for documentation, if flags are empty - */ - const doc_string& - label() const { - return label_; - } - - /** @brief sets parameter label; - * will be used for documentation, if flags are empty - */ - parameter& - label(const doc_string& lbl) { - label_ = lbl; - return *this; - } - - /** @brief sets parameter label; - * will be used for documentation, if flags are empty - */ - parameter& - label(doc_string&& lbl) { - label_ = lbl; - return *this; - } - - - //--------------------------------------------------------------- - /** @brief returns either longest matching prefix of 'arg' in any - * of the flags or the result of the custom match operation - */ - subrange - match(const arg_string& arg) const - { - if(flags_.empty()) { - return matcher_(arg); - } - else { - //empty flags are not allowed - if(arg.empty()) return subrange{}; - - if(std::find(flags_.begin(), flags_.end(), arg) != flags_.end()) { - return subrange{0,arg.size()}; - } - return str::longest_prefix_match(arg, flags_); - } - } - - - //--------------------------------------------------------------- - /** @brief access range of flag strings */ - const arg_list& - flags() const noexcept { - return flags_; - } - - /** @brief access custom match operation */ - const match_function& - matcher() const noexcept { - return matcher_; - } - - - //--------------------------------------------------------------- - /** @brief prepend prefix to each flag */ - inline friend parameter& - with_prefix(const arg_string& prefix, parameter& p) - { - if(prefix.empty() || p.flags().empty()) return p; - - for(auto& f : p.flags_) { - if(f.find(prefix) != 0) f.insert(0, prefix); - } - return p; - } - - - /** @brief prepend prefix to each flag - */ - inline friend parameter& - with_prefixes_short_long( - const arg_string& shortpfx, const arg_string& longpfx, - parameter& p) - { - if(shortpfx.empty() && longpfx.empty()) return p; - if(p.flags().empty()) return p; - - for(auto& f : p.flags_) { - if(f.size() == 1) { - if(f.find(shortpfx) != 0) f.insert(0, shortpfx); - } else { - if(f.find(longpfx) != 0) f.insert(0, longpfx); - } - } - return p; - } - - - //--------------------------------------------------------------- - /** @brief prepend suffix to each flag */ - inline friend parameter& - with_suffix(const arg_string& suffix, parameter& p) - { - if(suffix.empty() || p.flags().empty()) return p; - - for(auto& f : p.flags_) { - if(f.find(suffix) + suffix.size() != f.size()) { - f.insert(f.end(), suffix.begin(), suffix.end()); - } - } - return p; - } - - - /** @brief prepend suffix to each flag - */ - inline friend parameter& - with_suffixes_short_long( - const arg_string& shortsfx, const arg_string& longsfx, - parameter& p) - { - if(shortsfx.empty() && longsfx.empty()) return p; - if(p.flags().empty()) return p; - - for(auto& f : p.flags_) { - if(f.size() == 1) { - if(f.find(shortsfx) + shortsfx.size() != f.size()) { - f.insert(f.end(), shortsfx.begin(), shortsfx.end()); - } - } else { - if(f.find(longsfx) + longsfx.size() != f.size()) { - f.insert(f.end(), longsfx.begin(), longsfx.end()); - } - } - } - return p; - } - -private: - //--------------------------------------------------------------- - void add_flags(arg_string str) { - //empty flags are not allowed - str::remove_ws(str); - if(!str.empty()) flags_.push_back(std::move(str)); - } - - //--------------------------------------------------------------- - void add_flags(const arg_list& strs) { - if(strs.empty()) return; - flags_.reserve(flags_.size() + strs.size()); - for(const auto& s : strs) add_flags(s); - } - - template - void - add_flags(String1&& s1, String2&& s2, Strings&&... ss) { - flags_.reserve(2 + sizeof...(ss)); - add_flags(std::forward(s1)); - add_flags(std::forward(s2), std::forward(ss)...); - } - - arg_list flags_; - match_function matcher_; - doc_string label_; - bool required_ = false; - bool greedy_ = false; -}; - - - - -/*************************************************************************//** - * - * @brief makes required non-blocking exact match parameter - * - *****************************************************************************/ -template -inline parameter -command(String&& flag, Strings&&... flags) -{ - return parameter{std::forward(flag), std::forward(flags)...} - .required(true).blocking(true).repeatable(false); -} - - - -/*************************************************************************//** - * - * @brief makes required non-blocking exact match parameter - * - *****************************************************************************/ -template -inline parameter -required(String&& flag, Strings&&... flags) -{ - return parameter{std::forward(flag), std::forward(flags)...} - .required(true).blocking(false).repeatable(false); -} - - - -/*************************************************************************//** - * - * @brief makes optional, non-blocking exact match parameter - * - *****************************************************************************/ -template -inline parameter -option(String&& flag, Strings&&... flags) -{ - return parameter{std::forward(flag), std::forward(flags)...} - .required(false).blocking(false).repeatable(false); -} - - - -/*************************************************************************//** - * - * @brief makes required, blocking, repeatable value parameter; - * matches any non-empty string - * - *****************************************************************************/ -template -inline parameter -value(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::nonempty} - .label(label) - .target(std::forward(tgts)...) - .required(true).blocking(true).repeatable(false); -} - -template::value || - traits::is_callable::value>::type> -inline parameter -value(Filter&& filter, doc_string label, Targets&&... tgts) -{ - return parameter{std::forward(filter)} - .label(label) - .target(std::forward(tgts)...) - .required(true).blocking(true).repeatable(false); -} - - - -/*************************************************************************//** - * - * @brief makes required, blocking, repeatable value parameter; - * matches any non-empty string - * - *****************************************************************************/ -template -inline parameter -values(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::nonempty} - .label(label) - .target(std::forward(tgts)...) - .required(true).blocking(true).repeatable(true); -} - -template::value || - traits::is_callable::value>::type> -inline parameter -values(Filter&& filter, doc_string label, Targets&&... tgts) -{ - return parameter{std::forward(filter)} - .label(label) - .target(std::forward(tgts)...) - .required(true).blocking(true).repeatable(true); -} - - - -/*************************************************************************//** - * - * @brief makes optional, blocking value parameter; - * matches any non-empty string - * - *****************************************************************************/ -template -inline parameter -opt_value(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::nonempty} - .label(label) - .target(std::forward(tgts)...) - .required(false).blocking(false).repeatable(false); -} - -template::value || - traits::is_callable::value>::type> -inline parameter -opt_value(Filter&& filter, doc_string label, Targets&&... tgts) -{ - return parameter{std::forward(filter)} - .label(label) - .target(std::forward(tgts)...) - .required(false).blocking(false).repeatable(false); -} - - - -/*************************************************************************//** - * - * @brief makes optional, blocking, repeatable value parameter; - * matches any non-empty string - * - *****************************************************************************/ -template -inline parameter -opt_values(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::nonempty} - .label(label) - .target(std::forward(tgts)...) - .required(false).blocking(false).repeatable(true); -} - -template::value || - traits::is_callable::value>::type> -inline parameter -opt_values(Filter&& filter, doc_string label, Targets&&... tgts) -{ - return parameter{std::forward(filter)} - .label(label) - .target(std::forward(tgts)...) - .required(false).blocking(false).repeatable(true); -} - - - -/*************************************************************************//** - * - * @brief makes required, blocking value parameter; - * matches any string consisting of alphanumeric characters - * - *****************************************************************************/ -template -inline parameter -word(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::alphanumeric} - .label(label) - .target(std::forward(tgts)...) - .required(true).blocking(true).repeatable(false); -} - - - -/*************************************************************************//** - * - * @brief makes required, blocking, repeatable value parameter; - * matches any string consisting of alphanumeric characters - * - *****************************************************************************/ -template -inline parameter -words(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::alphanumeric} - .label(label) - .target(std::forward(tgts)...) - .required(true).blocking(true).repeatable(true); -} - - - -/*************************************************************************//** - * - * @brief makes optional, blocking value parameter; - * matches any string consisting of alphanumeric characters - * - *****************************************************************************/ -template -inline parameter -opt_word(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::alphanumeric} - .label(label) - .target(std::forward(tgts)...) - .required(false).blocking(false).repeatable(false); -} - - - -/*************************************************************************//** - * - * @brief makes optional, blocking, repeatable value parameter; - * matches any string consisting of alphanumeric characters - * - *****************************************************************************/ -template -inline parameter -opt_words(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::alphanumeric} - .label(label) - .target(std::forward(tgts)...) - .required(false).blocking(false).repeatable(true); -} - - - -/*************************************************************************//** - * - * @brief makes required, blocking value parameter; - * matches any string that represents a number - * - *****************************************************************************/ -template -inline parameter -number(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::numbers{}} - .label(label) - .target(std::forward(tgts)...) - .required(true).blocking(true).repeatable(false); -} - - - -/*************************************************************************//** - * - * @brief makes required, blocking, repeatable value parameter; - * matches any string that represents a number - * - *****************************************************************************/ -template -inline parameter -numbers(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::numbers{}} - .label(label) - .target(std::forward(tgts)...) - .required(true).blocking(true).repeatable(true); -} - - - -/*************************************************************************//** - * - * @brief makes optional, blocking value parameter; - * matches any string that represents a number - * - *****************************************************************************/ -template -inline parameter -opt_number(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::numbers{}} - .label(label) - .target(std::forward(tgts)...) - .required(false).blocking(false).repeatable(false); -} - - - -/*************************************************************************//** - * - * @brief makes optional, blocking, repeatable value parameter; - * matches any string that represents a number - * - *****************************************************************************/ -template -inline parameter -opt_numbers(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::numbers{}} - .label(label) - .target(std::forward(tgts)...) - .required(false).blocking(false).repeatable(true); -} - - - -/*************************************************************************//** - * - * @brief makes required, blocking value parameter; - * matches any string that represents an integer - * - *****************************************************************************/ -template -inline parameter -integer(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::integers{}} - .label(label) - .target(std::forward(tgts)...) - .required(true).blocking(true).repeatable(false); -} - - - -/*************************************************************************//** - * - * @brief makes required, blocking, repeatable value parameter; - * matches any string that represents an integer - * - *****************************************************************************/ -template -inline parameter -integers(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::integers{}} - .label(label) - .target(std::forward(tgts)...) - .required(true).blocking(true).repeatable(true); -} - - - -/*************************************************************************//** - * - * @brief makes optional, blocking value parameter; - * matches any string that represents an integer - * - *****************************************************************************/ -template -inline parameter -opt_integer(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::integers{}} - .label(label) - .target(std::forward(tgts)...) - .required(false).blocking(false).repeatable(false); -} - - - -/*************************************************************************//** - * - * @brief makes optional, blocking, repeatable value parameter; - * matches any string that represents an integer - * - *****************************************************************************/ -template -inline parameter -opt_integers(const doc_string& label, Targets&&... tgts) -{ - return parameter{match::integers{}} - .label(label) - .target(std::forward(tgts)...) - .required(false).blocking(false).repeatable(true); -} - - - -/*************************************************************************//** - * - * @brief makes catch-all value parameter - * - *****************************************************************************/ -template -inline parameter -any_other(Targets&&... tgts) -{ - return parameter{match::any} - .target(std::forward(tgts)...) - .required(false).blocking(false).repeatable(true); -} - - - -/*************************************************************************//** - * - * @brief makes catch-all value parameter with custom filter - * - *****************************************************************************/ -template::value || - traits::is_callable::value>::type> -inline parameter -any(Filter&& filter, Targets&&... tgts) -{ - return parameter{std::forward(filter)} - .target(std::forward(tgts)...) - .required(false).blocking(false).repeatable(true); -} - - - - -/*************************************************************************//** - * - * @brief group of parameters and/or other groups; - * can be configured to act as a group of alternatives (exclusive match) - * - *****************************************************************************/ -class group : - public detail::token -{ - //--------------------------------------------------------------- - /** - * @brief tagged union type that either stores a parameter or a group - * and provides a common interface to them - * could be replaced by std::variant in the future - * - * Note to future self: do NOT try again to do this with - * dynamic polymorphism; there are a couple of - * nasty problems associated with it and the implementation - * becomes bloated and needlessly complicated. - */ - template - struct child_t { - enum class type : char {param, group}; - public: - - explicit - child_t(const Param& v) : m_{v}, type_{type::param} {} - child_t( Param&& v) noexcept : m_{std::move(v)}, type_{type::param} {} - - explicit - child_t(const Group& g) : m_{g}, type_{type::group} {} - child_t( Group&& g) noexcept : m_{std::move(g)}, type_{type::group} {} - - child_t(const child_t& src): type_{src.type_} { - switch(type_) { - default: - case type::param: new(&m_)data{src.m_.param}; break; - case type::group: new(&m_)data{src.m_.group}; break; - } - } - - child_t(child_t&& src) noexcept : type_{src.type_} { - switch(type_) { - default: - case type::param: new(&m_)data{std::move(src.m_.param)}; break; - case type::group: new(&m_)data{std::move(src.m_.group)}; break; - } - } - - child_t& operator = (const child_t& src) { - destroy_content(); - type_ = src.type_; - switch(type_) { - default: - case type::param: new(&m_)data{src.m_.param}; break; - case type::group: new(&m_)data{src.m_.group}; break; - } - return *this; - } - - child_t& operator = (child_t&& src) noexcept { - destroy_content(); - type_ = src.type_; - switch(type_) { - default: - case type::param: new(&m_)data{std::move(src.m_.param)}; break; - case type::group: new(&m_)data{std::move(src.m_.group)}; break; - } - return *this; - } - - ~child_t() { - destroy_content(); - } - - const doc_string& - doc() const noexcept { - switch(type_) { - default: - case type::param: return m_.param.doc(); - case type::group: return m_.group.doc(); - } - } - - bool blocking() const noexcept { - switch(type_) { - case type::param: return m_.param.blocking(); - case type::group: return m_.group.blocking(); - default: return false; - } - } - bool repeatable() const noexcept { - switch(type_) { - case type::param: return m_.param.repeatable(); - case type::group: return m_.group.repeatable(); - default: return false; - } - } - bool required() const noexcept { - switch(type_) { - case type::param: return m_.param.required(); - case type::group: - return (m_.group.exclusive() && m_.group.all_required() ) || - (!m_.group.exclusive() && m_.group.any_required() ); - default: return false; - } - } - bool exclusive() const noexcept { - switch(type_) { - case type::group: return m_.group.exclusive(); - case type::param: - default: return false; - } - } - std::size_t param_count() const noexcept { - switch(type_) { - case type::group: return m_.group.param_count(); - case type::param: - default: return std::size_t(1); - } - } - std::size_t depth() const noexcept { - switch(type_) { - case type::group: return m_.group.depth(); - case type::param: - default: return std::size_t(0); - } - } - - void execute_actions(const arg_string& arg) const { - switch(type_) { - default: - case type::group: return; - case type::param: m_.param.execute_actions(arg); break; - } - - } - - void notify_repeated(arg_index idx) const { - switch(type_) { - default: - case type::group: return; - case type::param: m_.param.notify_repeated(idx); break; - } - } - void notify_missing(arg_index idx) const { - switch(type_) { - default: - case type::group: return; - case type::param: m_.param.notify_missing(idx); break; - } - } - void notify_blocked(arg_index idx) const { - switch(type_) { - default: - case type::group: return; - case type::param: m_.param.notify_blocked(idx); break; - } - } - void notify_conflict(arg_index idx) const { - switch(type_) { - default: - case type::group: return; - case type::param: m_.param.notify_conflict(idx); break; - } - } - - bool is_param() const noexcept { return type_ == type::param; } - bool is_group() const noexcept { return type_ == type::group; } - - Param& as_param() noexcept { return m_.param; } - Group& as_group() noexcept { return m_.group; } - - const Param& as_param() const noexcept { return m_.param; } - const Group& as_group() const noexcept { return m_.group; } - - private: - void destroy_content() { - switch(type_) { - default: - case type::param: m_.param.~Param(); break; - case type::group: m_.group.~Group(); break; - } - } - - union data { - data() {} - - data(const Param& v) : param{v} {} - data( Param&& v) noexcept : param{std::move(v)} {} - - data(const Group& g) : group{g} {} - data( Group&& g) noexcept : group{std::move(g)} {} - ~data() {} - - Param param; - Group group; - }; - - data m_; - type type_; - }; - - -public: - //--------------------------------------------------------------- - using child = child_t; - using value_type = child; - -private: - using children_store = std::vector; - -public: - using const_iterator = children_store::const_iterator; - using iterator = children_store::iterator; - using size_type = children_store::size_type; - - - //--------------------------------------------------------------- - /** - * @brief recursively iterates over all nodes - */ - class depth_first_traverser - { - public: - //----------------------------------------------------- - struct context { - context() = default; - context(const group& p): - parent{&p}, cur{p.begin()}, end{p.end()} - {} - const group* parent = nullptr; - const_iterator cur; - const_iterator end; - }; - using context_list = std::vector; - - //----------------------------------------------------- - class memento { - friend class depth_first_traverser; - int level_; - context context_; - public: - int level() const noexcept { return level_; } - const child* param() const noexcept { return &(*context_.cur); } - }; - - depth_first_traverser() = default; - - explicit - depth_first_traverser(const group& cur): stack_{} { - if(!cur.empty()) stack_.emplace_back(cur); - } - - explicit operator bool() const noexcept { - return !stack_.empty(); - } - - int level() const noexcept { - return int(stack_.size()); - } - - bool is_first_in_parent() const noexcept { - if(stack_.empty()) return false; - return (stack_.back().cur == stack_.back().parent->begin()); - } - - bool is_last_in_parent() const noexcept { - if(stack_.empty()) return false; - return (stack_.back().cur+1 == stack_.back().end); - } - - bool is_last_in_path() const noexcept { - if(stack_.empty()) return false; - for(const auto& t : stack_) { - if(t.cur+1 != t.end) return false; - } - const auto& top = stack_.back(); - //if we have to descend into group on next ++ => not last in path - if(top.cur->is_group()) return false; - return true; - } - - /** @brief inside a group of alternatives >= minlevel */ - bool is_alternative(int minlevel = 0) const noexcept { - if(stack_.empty()) return false; - if(minlevel > 0) minlevel -= 1; - if(minlevel >= int(stack_.size())) return false; - return std::any_of(stack_.begin() + minlevel, stack_.end(), - [](const context& c) { return c.parent->exclusive(); }); - } - - /** @brief repeatable or inside a repeatable group >= minlevel */ - bool is_repeatable(int minlevel = 0) const noexcept { - if(stack_.empty()) return false; - if(stack_.back().cur->repeatable()) return true; - if(minlevel > 0) minlevel -= 1; - if(minlevel >= int(stack_.size())) return false; - return std::any_of(stack_.begin() + minlevel, stack_.end(), - [](const context& c) { return c.parent->repeatable(); }); - } - - /** @brief inside a particular group */ - bool is_inside(const group* g) const noexcept { - if(!g) return false; - return std::any_of(stack_.begin(), stack_.end(), - [g](const context& c) { return c.parent == g; }); - } - - /** @brief inside group with joinable flags */ - bool joinable() const noexcept { - if(stack_.empty()) return false; - return std::any_of(stack_.begin(), stack_.end(), - [](const context& c) { return c.parent->joinable(); }); - } - - const context_list& - stack() const { - return stack_; - } - - /** @brief innermost repeat group */ - const group* - innermost_repeat_group() const noexcept { - auto i = std::find_if(stack_.rbegin(), stack_.rend(), - [](const context& c) { return c.parent->repeatable(); }); - return i != stack_.rend() ? i->parent : nullptr; - } - - /** @brief innermost exclusive (alternatives) group */ - const group* - innermost_exclusive_group() const noexcept { - auto i = std::find_if(stack_.rbegin(), stack_.rend(), - [](const context& c) { return c.parent->exclusive(); }); - return i != stack_.rend() ? i->parent : nullptr; - } - - /** @brief innermost blocking group */ - const group* - innermost_blocking_group() const noexcept { - auto i = std::find_if(stack_.rbegin(), stack_.rend(), - [](const context& c) { return c.parent->blocking(); }); - return i != stack_.rend() ? i->parent : nullptr; - } - - /** @brief returns the outermost group that will be left on next ++*/ - const group* - outermost_blocking_group_fully_explored() const noexcept { - if(stack_.empty()) return nullptr; - - const group* g = nullptr; - for(auto i = stack_.rbegin(); i != stack_.rend(); ++i) { - if(i->cur+1 == i->end) { - if(i->parent->blocking()) g = i->parent; - } else { - return g; - } - } - return g; - } - - /** @brief outermost join group */ - const group* - outermost_join_group() const noexcept { - auto i = std::find_if(stack_.begin(), stack_.end(), - [](const context& c) { return c.parent->joinable(); }); - return i != stack_.end() ? i->parent : nullptr; - } - - const group* root() const noexcept { - return stack_.empty() ? nullptr : stack_.front().parent; - } - - /** @brief common flag prefix of all flags in current group */ - arg_string common_flag_prefix() const noexcept { - if(stack_.empty()) return ""; - auto g = outermost_join_group(); - return g ? g->common_flag_prefix() : arg_string(""); - } - - const child& - operator * () const noexcept { - return *stack_.back().cur; - } - - const child* - operator -> () const noexcept { - return &(*stack_.back().cur); - } - - const group& - parent() const noexcept { - return *(stack_.back().parent); - } - - - /** @brief go to next element of depth first search */ - depth_first_traverser& - operator ++ () { - if(stack_.empty()) return *this; - //at group -> decend into group - if(stack_.back().cur->is_group()) { - stack_.emplace_back(stack_.back().cur->as_group()); - } - else { - next_sibling(); - } - return *this; - } - - /** @brief go to next sibling of current */ - depth_first_traverser& - next_sibling() { - if(stack_.empty()) return *this; - ++stack_.back().cur; - //at the end of current group? - while(stack_.back().cur == stack_.back().end) { - //go to parent - stack_.pop_back(); - if(stack_.empty()) return *this; - //go to next sibling in parent - ++stack_.back().cur; - } - return *this; - } - - /** @brief go to next position after siblings of current */ - depth_first_traverser& - next_after_siblings() { - if(stack_.empty()) return *this; - stack_.back().cur = stack_.back().end-1; - next_sibling(); - return *this; - } - - /** - * @brief - */ - depth_first_traverser& - back_to_ancestor(const group* g) { - if(!g) return *this; - while(!stack_.empty()) { - const auto& top = stack_.back().cur; - if(top->is_group() && &(top->as_group()) == g) return *this; - stack_.pop_back(); - } - return *this; - } - - /** @brief don't visit next siblings, go back to parent on next ++ - * note: renders siblings unreachable for *this - **/ - depth_first_traverser& - skip_siblings() { - if(stack_.empty()) return *this; - //future increments won't visit subsequent siblings: - stack_.back().end = stack_.back().cur+1; - return *this; - } - - /** @brief skips all other alternatives in surrounding exclusive groups - * on next ++ - * note: renders alternatives unreachable for *this - */ - depth_first_traverser& - skip_alternatives() { - if(stack_.empty()) return *this; - - //exclude all other alternatives in surrounding groups - //by making their current position the last one - for(auto& c : stack_) { - if(c.parent && c.parent->exclusive() && c.cur < c.end) - c.end = c.cur+1; - } - - return *this; - } - - void invalidate() { - stack_.clear(); - } - - inline friend bool operator == (const depth_first_traverser& a, - const depth_first_traverser& b) - { - if(a.stack_.empty() || b.stack_.empty()) return false; - - //parents not the same -> different position - if(a.stack_.back().parent != b.stack_.back().parent) return false; - - bool aEnd = a.stack_.back().cur == a.stack_.back().end; - bool bEnd = b.stack_.back().cur == b.stack_.back().end; - //either both at the end of the same parent => same position - if(aEnd && bEnd) return true; - //or only one at the end => not at the same position - if(aEnd || bEnd) return false; - return std::addressof(*a.stack_.back().cur) == - std::addressof(*b.stack_.back().cur); - } - inline friend bool operator != (const depth_first_traverser& a, - const depth_first_traverser& b) - { - return !(a == b); - } - - memento - undo_point() const { - memento m; - m.level_ = int(stack_.size()); - if(!stack_.empty()) m.context_ = stack_.back(); - return m; - } - - void undo(const memento& m) { - if(m.level_ < 1) return; - if(m.level_ <= int(stack_.size())) { - stack_.erase(stack_.begin() + m.level_, stack_.end()); - stack_.back() = m.context_; - } - else if(stack_.empty() && m.level_ == 1) { - stack_.push_back(m.context_); - } - } - - private: - context_list stack_; - }; - - - //--------------------------------------------------------------- - group() = default; - - template - explicit - group(doc_string docstr, Param param, Params... params): - children_{}, exclusive_{false}, joinable_{false}, scoped_{true} - { - doc(std::move(docstr)); - push_back(std::move(param), std::move(params)...); - } - - template - explicit - group(parameter param, Params... params): - children_{}, exclusive_{false}, joinable_{false}, scoped_{true} - { - push_back(std::move(param), std::move(params)...); - } - - template - explicit - group(group p1, P2 p2, Ps... ps): - children_{}, exclusive_{false}, joinable_{false}, scoped_{true} - { - push_back(std::move(p1), std::move(p2), std::move(ps)...); - } - - - //----------------------------------------------------- - group(const group&) = default; - group(group&&) = default; - - - //--------------------------------------------------------------- - group& operator = (const group&) = default; - group& operator = (group&&) = default; - - - //--------------------------------------------------------------- - /** @brief determines if a command line argument can be matched by a - * combination of (partial) matches through any number of children - */ - group& joinable(bool yes) { - joinable_ = yes; - return *this; - } - - /** @brief returns if a command line argument can be matched by a - * combination of (partial) matches through any number of children - */ - bool joinable() const noexcept { - return joinable_; - } - - - //--------------------------------------------------------------- - /** @brief turns explicit scoping on or off - * operators , & | and other combinating functions will - * not merge groups that are marked as scoped - */ - group& scoped(bool yes) { - scoped_ = yes; - return *this; - } - - /** @brief returns true if operators , & | and other combinating functions - * will merge groups and false otherwise - */ - bool scoped() const noexcept - { - return scoped_; - } - - - //--------------------------------------------------------------- - /** @brief determines if children are mutually exclusive alternatives */ - group& exclusive(bool yes) { - exclusive_ = yes; - return *this; - } - /** @brief returns if children are mutually exclusive alternatives */ - bool exclusive() const noexcept { - return exclusive_; - } - - - //--------------------------------------------------------------- - /** @brief returns true, if any child is required to match */ - bool any_required() const - { - return std::any_of(children_.begin(), children_.end(), - [](const child& n){ return n.required(); }); - } - /** @brief returns true, if all children are required to match */ - bool all_required() const - { - return std::all_of(children_.begin(), children_.end(), - [](const child& n){ return n.required(); }); - } - - - //--------------------------------------------------------------- - /** @brief returns true if any child is optional (=non-required) */ - bool any_optional() const { - return !all_required(); - } - /** @brief returns true if all children are optional (=non-required) */ - bool all_optional() const { - return !any_required(); - } - - - //--------------------------------------------------------------- - /** @brief returns if the entire group is blocking / positional */ - bool blocking() const noexcept { - return token::blocking() || (exclusive() && all_blocking()); - } - //----------------------------------------------------- - /** @brief determines if the entire group is blocking / positional */ - group& blocking(bool yes) { - return token::blocking(yes); - } - - //--------------------------------------------------------------- - /** @brief returns true if any child is blocking */ - bool any_blocking() const - { - return std::any_of(children_.begin(), children_.end(), - [](const child& n){ return n.blocking(); }); - } - //--------------------------------------------------------------- - /** @brief returns true if all children is blocking */ - bool all_blocking() const - { - return std::all_of(children_.begin(), children_.end(), - [](const child& n){ return n.blocking(); }); - } - - - //--------------------------------------------------------------- - /** @brief returns if any child is a value parameter (recursive) */ - bool any_flagless() const - { - return std::any_of(children_.begin(), children_.end(), - [](const child& p){ - return p.is_param() && p.as_param().flags().empty(); - }); - } - /** @brief returns if all children are value parameters (recursive) */ - bool all_flagless() const - { - return std::all_of(children_.begin(), children_.end(), - [](const child& p){ - return p.is_param() && p.as_param().flags().empty(); - }); - } - - - //--------------------------------------------------------------- - /** @brief adds child parameter at the end */ - group& - push_back(const parameter& v) { - children_.emplace_back(v); - return *this; - } - //----------------------------------------------------- - /** @brief adds child parameter at the end */ - group& - push_back(parameter&& v) { - children_.emplace_back(std::move(v)); - return *this; - } - //----------------------------------------------------- - /** @brief adds child group at the end */ - group& - push_back(const group& g) { - children_.emplace_back(g); - return *this; - } - //----------------------------------------------------- - /** @brief adds child group at the end */ - group& - push_back(group&& g) { - children_.emplace_back(std::move(g)); - return *this; - } - - - //----------------------------------------------------- - /** @brief adds children (groups and/or parameters) */ - template - group& - push_back(Param1&& param1, Param2&& param2, Params&&... params) - { - children_.reserve(children_.size() + 2 + sizeof...(params)); - push_back(std::forward(param1)); - push_back(std::forward(param2), std::forward(params)...); - return *this; - } - - - //--------------------------------------------------------------- - /** @brief adds child parameter at the beginning */ - group& - push_front(const parameter& v) { - children_.emplace(children_.begin(), v); - return *this; - } - //----------------------------------------------------- - /** @brief adds child parameter at the beginning */ - group& - push_front(parameter&& v) { - children_.emplace(children_.begin(), std::move(v)); - return *this; - } - //----------------------------------------------------- - /** @brief adds child group at the beginning */ - group& - push_front(const group& g) { - children_.emplace(children_.begin(), g); - return *this; - } - //----------------------------------------------------- - /** @brief adds child group at the beginning */ - group& - push_front(group&& g) { - children_.emplace(children_.begin(), std::move(g)); - return *this; - } - - - //--------------------------------------------------------------- - /** @brief adds all children of other group at the end */ - group& - merge(group&& g) - { - children_.insert(children_.end(), - std::make_move_iterator(g.begin()), - std::make_move_iterator(g.end())); - return *this; - } - //----------------------------------------------------- - /** @brief adds all children of several other groups at the end */ - template - group& - merge(group&& g1, group&& g2, Groups&&... gs) - { - merge(std::move(g1)); - merge(std::move(g2), std::forward(gs)...); - return *this; - } - - - //--------------------------------------------------------------- - /** @brief indexed, nutable access to child */ - child& operator [] (size_type index) noexcept { - return children_[index]; - } - /** @brief indexed, non-nutable access to child */ - const child& operator [] (size_type index) const noexcept { - return children_[index]; - } - - //--------------------------------------------------------------- - /** @brief mutable access to first child */ - child& front() noexcept { return children_.front(); } - /** @brief non-mutable access to first child */ - const child& front() const noexcept { return children_.front(); } - //----------------------------------------------------- - /** @brief mutable access to last child */ - child& back() noexcept { return children_.back(); } - /** @brief non-mutable access to last child */ - const child& back() const noexcept { return children_.back(); } - - - //--------------------------------------------------------------- - /** @brief returns true, if group has no children, false otherwise */ - bool empty() const noexcept { return children_.empty(); } - - /** @brief returns number of children */ - size_type size() const noexcept { return children_.size(); } - - /** @brief returns number of nested levels; 1 for a flat group */ - size_type depth() const { - size_type n = 0; - for(const auto& c : children_) { - auto l = 1 + c.depth(); - if(l > n) n = l; - } - return n; - } - - - //--------------------------------------------------------------- - /** @brief returns mutating iterator to position of first element */ - iterator begin() noexcept { return children_.begin(); } - /** @brief returns non-mutating iterator to position of first element */ - const_iterator begin() const noexcept { return children_.begin(); } - /** @brief returns non-mutating iterator to position of first element */ - const_iterator cbegin() const noexcept { return children_.begin(); } - - /** @brief returns mutating iterator to position one past the last element */ - iterator end() noexcept { return children_.end(); } - /** @brief returns non-mutating iterator to position one past the last element */ - const_iterator end() const noexcept { return children_.end(); } - /** @brief returns non-mutating iterator to position one past the last element */ - const_iterator cend() const noexcept { return children_.end(); } - - - //--------------------------------------------------------------- - /** @brief returns augmented iterator for depth first searches - * @details traverser knows end of iteration and can skip over children - */ - depth_first_traverser - begin_dfs() const noexcept { - return depth_first_traverser{*this}; - } - - - //--------------------------------------------------------------- - /** @brief returns recursive parameter count */ - size_type param_count() const { - size_type c = 0; - for(const auto& n : children_) { - c += n.param_count(); - } - return c; - } - - - //--------------------------------------------------------------- - /** @brief returns range of all flags (recursive) */ - arg_list all_flags() const - { - std::vector all; - gather_flags(children_, all); - return all; - } - - /** @brief returns true, if no flag occurs as true - * prefix of any other flag (identical flags will be ignored) */ - bool flags_are_prefix_free() const - { - const auto fs = all_flags(); - - using std::begin; using std::end; - for(auto i = begin(fs), e = end(fs); i != e; ++i) { - if(!i->empty()) { - for(auto j = i+1; j != e; ++j) { - if(!j->empty() && *i != *j) { - if(i->find(*j) == 0) return false; - if(j->find(*i) == 0) return false; - } - } - } - } - - return true; - } - - - //--------------------------------------------------------------- - /** @brief returns longest common prefix of all flags */ - arg_string common_flag_prefix() const - { - arg_list prefixes; - gather_prefixes(children_, prefixes); - return str::longest_common_prefix(prefixes); - } - - -private: - //--------------------------------------------------------------- - static void - gather_flags(const children_store& nodes, arg_list& all) - { - for(const auto& p : nodes) { - if(p.is_group()) { - gather_flags(p.as_group().children_, all); - } - else { - const auto& pf = p.as_param().flags(); - using std::begin; - using std::end; - if(!pf.empty()) all.insert(end(all), begin(pf), end(pf)); - } - } - } - //--------------------------------------------------------------- - static void - gather_prefixes(const children_store& nodes, arg_list& all) - { - for(const auto& p : nodes) { - if(p.is_group()) { - gather_prefixes(p.as_group().children_, all); - } - else if(!p.as_param().flags().empty()) { - auto pfx = str::longest_common_prefix(p.as_param().flags()); - if(!pfx.empty()) all.push_back(std::move(pfx)); - } - } - } - - //--------------------------------------------------------------- - children_store children_; - bool exclusive_ = false; - bool joinable_ = false; - bool scoped_ = false; -}; - - - -/*************************************************************************//** - * - * @brief group or parameter - * - *****************************************************************************/ -using pattern = group::child; - - - -/*************************************************************************//** - * - * @brief apply an action to all parameters in a group - * - *****************************************************************************/ -template -void for_all_params(group& g, Action&& action) -{ - for(auto& p : g) { - if(p.is_group()) { - for_all_params(p.as_group(), action); - } - else { - action(p.as_param()); - } - } -} - -template -void for_all_params(const group& g, Action&& action) -{ - for(auto& p : g) { - if(p.is_group()) { - for_all_params(p.as_group(), action); - } - else { - action(p.as_param()); - } - } -} - - - -/*************************************************************************//** - * - * @brief makes a group of parameters and/or groups - * - *****************************************************************************/ -inline group -operator , (parameter a, parameter b) -{ - return group{std::move(a), std::move(b)}.scoped(false); -} - -//--------------------------------------------------------- -inline group -operator , (parameter a, group b) -{ - return !b.scoped() && !b.blocking() && !b.exclusive() && !b.repeatable() - && !b.joinable() && (b.doc().empty() || b.doc() == a.doc()) - ? b.push_front(std::move(a)) - : group{std::move(a), std::move(b)}.scoped(false); -} - -//--------------------------------------------------------- -inline group -operator , (group a, parameter b) -{ - return !a.scoped() && !a.blocking() && !a.exclusive() && !a.repeatable() - && !a.joinable() && (a.doc().empty() || a.doc() == b.doc()) - ? a.push_back(std::move(b)) - : group{std::move(a), std::move(b)}.scoped(false); -} - -//--------------------------------------------------------- -inline group -operator , (group a, group b) -{ - return !a.scoped() && !a.blocking() && !a.exclusive() && !a.repeatable() - && !a.joinable() && (a.doc().empty() || a.doc() == b.doc()) - ? a.push_back(std::move(b)) - : group{std::move(a), std::move(b)}.scoped(false); -} - - - -/*************************************************************************//** - * - * @brief makes a group of alternative parameters or groups - * - *****************************************************************************/ -template -inline group -one_of(Param param, Params... params) -{ - return group{std::move(param), std::move(params)...}.exclusive(true); -} - - -/*************************************************************************//** - * - * @brief makes a group of alternative parameters or groups - * - *****************************************************************************/ -inline group -operator | (parameter a, parameter b) -{ - return group{std::move(a), std::move(b)}.scoped(false).exclusive(true); -} - -//------------------------------------------------------------------- -inline group -operator | (parameter a, group b) -{ - return !b.scoped() && !b.blocking() && b.exclusive() && !b.repeatable() - && !b.joinable() - && (b.doc().empty() || b.doc() == a.doc()) - ? b.push_front(std::move(a)) - : group{std::move(a), std::move(b)}.scoped(false).exclusive(true); -} - -//------------------------------------------------------------------- -inline group -operator | (group a, parameter b) -{ - return !a.scoped() && a.exclusive() && !a.repeatable() && !a.joinable() - && a.blocking() == b.blocking() - && (a.doc().empty() || a.doc() == b.doc()) - ? a.push_back(std::move(b)) - : group{std::move(a), std::move(b)}.scoped(false).exclusive(true); -} - -inline group -operator | (group a, group b) -{ - return !a.scoped() && a.exclusive() &&!a.repeatable() && !a.joinable() - && a.blocking() == b.blocking() - && (a.doc().empty() || a.doc() == b.doc()) - ? a.push_back(std::move(b)) - : group{std::move(a), std::move(b)}.scoped(false).exclusive(true); -} - - - -/*************************************************************************//** - * - * @brief helpers (NOT FOR DIRECT USE IN CLIENT CODE!) - * no interface guarantees; might be changed or removed in the future - * - *****************************************************************************/ -namespace detail { - -inline void set_blocking(bool) {} - -template -void set_blocking(bool yes, P& p, Ps&... ps) { - p.blocking(yes); - set_blocking(yes, ps...); -} - -} // namespace detail - - -/*************************************************************************//** - * - * @brief makes a parameter/group sequence by making all input objects blocking - * - *****************************************************************************/ -template -inline group -in_sequence(Param param, Params... params) -{ - detail::set_blocking(true, param, params...); - return group{std::move(param), std::move(params)...}.scoped(true); -} - - -/*************************************************************************//** - * - * @brief makes a parameter/group sequence by making all input objects blocking - * - *****************************************************************************/ -inline group -operator & (parameter a, parameter b) -{ - a.blocking(true); - b.blocking(true); - return group{std::move(a), std::move(b)}.scoped(true); -} - -//--------------------------------------------------------- -inline group -operator & (parameter a, group b) -{ - a.blocking(true); - return group{std::move(a), std::move(b)}.scoped(true); -} - -//--------------------------------------------------------- -inline group -operator & (group a, parameter b) -{ - b.blocking(true); - if(a.all_blocking() && !a.exclusive() && !a.repeatable() && !a.joinable() - && (a.doc().empty() || a.doc() == b.doc())) - { - return a.push_back(std::move(b)); - } - else { - if(!a.all_blocking()) a.blocking(true); - return group{std::move(a), std::move(b)}.scoped(true); - } -} - -inline group -operator & (group a, group b) -{ - if(!b.all_blocking()) b.blocking(true); - if(a.all_blocking() && !a.exclusive() && !a.repeatable() - && !a.joinable() && (a.doc().empty() || a.doc() == b.doc())) - { - return a.push_back(std::move(b)); - } - else { - if(!a.all_blocking()) a.blocking(true); - return group{std::move(a), std::move(b)}.scoped(true); - } -} - - - -/*************************************************************************//** - * - * @brief makes a group of parameters and/or groups - * where all single char flag params ("-a", "b", ...) are joinable - * - *****************************************************************************/ -inline group -joinable(group g) { - return g.joinable(true); -} - -//------------------------------------------------------------------- -template -inline group -joinable(parameter param, Params... params) -{ - return group{std::move(param), std::move(params)...}.joinable(true); -} - -template -inline group -joinable(group p1, P2 p2, Ps... ps) -{ - return group{std::move(p1), std::move(p2), std::move(ps)...}.joinable(true); -} - -template -inline group -joinable(doc_string docstr, Param param, Params... params) -{ - return group{std::move(param), std::move(params)...} - .joinable(true).doc(std::move(docstr)); -} - - - -/*************************************************************************//** - * - * @brief makes a repeatable copy of a parameter - * - *****************************************************************************/ -inline parameter -repeatable(parameter p) { - return p.repeatable(true); -} - -/*************************************************************************//** - * - * @brief makes a repeatable copy of a group - * - *****************************************************************************/ -inline group -repeatable(group g) { - return g.repeatable(true); -} - - - -/*************************************************************************//** - * - * @brief makes a group of parameters and/or groups - * that is repeatable as a whole - * Note that a repeatable group consisting entirely of non-blocking - * children is equivalent to a non-repeatable group of - * repeatable children. - * - *****************************************************************************/ -template -inline group -repeatable(parameter p1, P2 p2, Ps... ps) -{ - return group{std::move(p1), std::move(p2), - std::move(ps)...}.repeatable(true); -} - -template -inline group -repeatable(group p1, P2 p2, Ps... ps) -{ - return group{std::move(p1), std::move(p2), - std::move(ps)...}.repeatable(true); -} - - - -/*************************************************************************//** - * - * @brief makes a parameter greedy (match with top priority) - * - *****************************************************************************/ -inline parameter -greedy(parameter p) { - return p.greedy(true); -} - -inline parameter -operator ! (parameter p) { - return greedy(p); -} - - - -/*************************************************************************//** - * - * @brief recursively prepends a prefix to all flags - * - *****************************************************************************/ -inline parameter&& -with_prefix(const arg_string& prefix, parameter&& p) { - return std::move(with_prefix(prefix, p)); -} - - -//------------------------------------------------------------------- -inline group& -with_prefix(const arg_string& prefix, group& g) -{ - for(auto& p : g) { - if(p.is_group()) { - with_prefix(prefix, p.as_group()); - } else { - with_prefix(prefix, p.as_param()); - } - } - return g; -} - - -inline group&& -with_prefix(const arg_string& prefix, group&& params) -{ - return std::move(with_prefix(prefix, params)); -} - - -template -inline group -with_prefix(arg_string prefix, Param&& param, Params&&... params) -{ - return with_prefix(prefix, group{std::forward(param), - std::forward(params)...}); -} - - - -/*************************************************************************//** - * - * @brief recursively prepends a prefix to all flags - * - * @param shortpfx : used for single-letter flags - * @param longpfx : used for flags with length > 1 - * - *****************************************************************************/ -inline parameter&& -with_prefixes_short_long(const arg_string& shortpfx, const arg_string& longpfx, - parameter&& p) -{ - return std::move(with_prefixes_short_long(shortpfx, longpfx, p)); -} - - -//------------------------------------------------------------------- -inline group& -with_prefixes_short_long(const arg_string& shortFlagPrefix, - const arg_string& longFlagPrefix, - group& g) -{ - for(auto& p : g) { - if(p.is_group()) { - with_prefixes_short_long(shortFlagPrefix, longFlagPrefix, p.as_group()); - } else { - with_prefixes_short_long(shortFlagPrefix, longFlagPrefix, p.as_param()); - } - } - return g; -} - - -inline group&& -with_prefixes_short_long(const arg_string& shortFlagPrefix, - const arg_string& longFlagPrefix, - group&& params) -{ - return std::move(with_prefixes_short_long(shortFlagPrefix, longFlagPrefix, - params)); -} - - -template -inline group -with_prefixes_short_long(const arg_string& shortFlagPrefix, - const arg_string& longFlagPrefix, - Param&& param, Params&&... params) -{ - return with_prefixes_short_long(shortFlagPrefix, longFlagPrefix, - group{std::forward(param), - std::forward(params)...}); -} - - - -/*************************************************************************//** - * - * @brief recursively prepends a suffix to all flags - * - *****************************************************************************/ -inline parameter&& -with_suffix(const arg_string& suffix, parameter&& p) { - return std::move(with_suffix(suffix, p)); -} - - -//------------------------------------------------------------------- -inline group& -with_suffix(const arg_string& suffix, group& g) -{ - for(auto& p : g) { - if(p.is_group()) { - with_suffix(suffix, p.as_group()); - } else { - with_suffix(suffix, p.as_param()); - } - } - return g; -} - - -inline group&& -with_suffix(const arg_string& suffix, group&& params) -{ - return std::move(with_suffix(suffix, params)); -} - - -template -inline group -with_suffix(arg_string suffix, Param&& param, Params&&... params) -{ - return with_suffix(suffix, group{std::forward(param), - std::forward(params)...}); -} - - - -/*************************************************************************//** - * - * @brief recursively prepends a suffix to all flags - * - * @param shortsfx : used for single-letter flags - * @param longsfx : used for flags with length > 1 - * - *****************************************************************************/ -inline parameter&& -with_suffixes_short_long(const arg_string& shortsfx, const arg_string& longsfx, - parameter&& p) -{ - return std::move(with_suffixes_short_long(shortsfx, longsfx, p)); -} - - -//------------------------------------------------------------------- -inline group& -with_suffixes_short_long(const arg_string& shortFlagSuffix, - const arg_string& longFlagSuffix, - group& g) -{ - for(auto& p : g) { - if(p.is_group()) { - with_suffixes_short_long(shortFlagSuffix, longFlagSuffix, p.as_group()); - } else { - with_suffixes_short_long(shortFlagSuffix, longFlagSuffix, p.as_param()); - } - } - return g; -} - - -inline group&& -with_suffixes_short_long(const arg_string& shortFlagSuffix, - const arg_string& longFlagSuffix, - group&& params) -{ - return std::move(with_suffixes_short_long(shortFlagSuffix, longFlagSuffix, - params)); -} - - -template -inline group -with_suffixes_short_long(const arg_string& shortFlagSuffix, - const arg_string& longFlagSuffix, - Param&& param, Params&&... params) -{ - return with_suffixes_short_long(shortFlagSuffix, longFlagSuffix, - group{std::forward(param), - std::forward(params)...}); -} - - - - - - - - -/*************************************************************************//** - * - * @brief parsing implementation details - * - *****************************************************************************/ - -namespace detail { - - -/*************************************************************************//** - * - * @brief DFS traverser that keeps track of 'scopes' - * scope = all parameters that are either bounded by - * two blocking parameters on the same depth level - * or the beginning/end of the outermost group - * - *****************************************************************************/ -class scoped_dfs_traverser -{ -public: - using dfs_traverser = group::depth_first_traverser; - - scoped_dfs_traverser() = default; - - explicit - scoped_dfs_traverser(const group& g): - pos_{g}, lastMatch_{}, posAfterLastMatch_{}, scopes_{}, - ignoreBlocks_{false}, - repeatGroupStarted_{false}, repeatGroupContinues_{false} - {} - - const dfs_traverser& base() const noexcept { return pos_; } - const dfs_traverser& last_match() const noexcept { return lastMatch_; } - - const group& parent() const noexcept { return pos_.parent(); } - - const group* innermost_repeat_group() const noexcept { - return pos_.innermost_repeat_group(); - } - const group* outermost_join_group() const noexcept { - return pos_.outermost_join_group(); - } - const group* innermost_blocking_group() const noexcept { - return pos_.innermost_blocking_group(); - } - const group* innermost_exclusive_group() const noexcept { - return pos_.innermost_exclusive_group(); - } - - const pattern* operator ->() const noexcept { return pos_.operator->(); } - const pattern& operator *() const noexcept { return *pos_; } - - const pattern* ptr() const noexcept { return pos_.operator->(); } - - explicit operator bool() const noexcept { return bool(pos_); } - - bool joinable() const noexcept { return pos_.joinable(); } - arg_string common_flag_prefix() const { return pos_.common_flag_prefix(); } - - void ignore_blocking(bool yes) { ignoreBlocks_ = yes; } - - void invalidate() { - pos_.invalidate(); - } - - bool matched() const noexcept { - return (pos_ == lastMatch_); - } - - bool start_of_repeat_group() const noexcept { return repeatGroupStarted_; } - - //----------------------------------------------------- - scoped_dfs_traverser& - next_sibling() { pos_.next_sibling(); return *this; } - - scoped_dfs_traverser& - next_after_siblings() { pos_.next_after_siblings(); return *this; } - - - //----------------------------------------------------- - scoped_dfs_traverser& - operator ++ () - { - if(!pos_) return *this; - - if(pos_.is_last_in_path()) { - return_to_outermost_scope(); - return *this; - } - - //current pattern can block if it didn't match already - if(ignoreBlocks_ || matched()) { - ++pos_; - } - else if(!pos_->is_group()) { - //current group can block if we didn't have any match in it - const group* g = pos_.outermost_blocking_group_fully_explored(); - //no match in 'g' before -> skip to after its siblings - if(g && !lastMatch_.is_inside(g)) { - pos_.back_to_ancestor(g).next_after_siblings(); - if(!pos_) return_to_outermost_scope(); - } - else if(pos_->blocking()) { - if(pos_.parent().exclusive()) { - pos_.next_sibling(); - } else { - //no match => skip siblings of blocking param - pos_.next_after_siblings(); - } - if(!pos_) return_to_outermost_scope(); - } else { - ++pos_; - } - } else { - ++pos_; - } - check_if_left_scope(); - return *this; - } - - //----------------------------------------------------- - void next_after_match(scoped_dfs_traverser match) - { - if(!match || ignoreBlocks_) return; - - check_repeat_group_start(match); - - lastMatch_ = match.base(); - - // if there is a blocking ancestor -> go back to it - if(!match->blocking()) { - match.pos_.back_to_ancestor(match.innermost_blocking_group()); - } - - //if match is not in current position & current position is blocking - //=> current position has to be advanced by one so that it is - //no longer reachable within current scope - //(can happen for repeatable, blocking parameters) - if(match.base() != pos_ && pos_->blocking()) pos_.next_sibling(); - - if(match->blocking()) { - if(match.pos_.is_alternative()) { - //discard other alternatives - match.pos_.skip_alternatives(); - } - - if(is_last_in_current_scope(match.pos_)) { - //if current param is not repeatable -> back to previous scope - if(!match->repeatable() && !match->is_group()) { - pos_ = std::move(match.pos_); - if(!scopes_.empty()) pos_.undo(scopes_.top()); - } - else { //stay at match position - pos_ = std::move(match.pos_); - } - } - else { //not last in current group - //if current param is not repeatable, go directly to next - if(!match->repeatable() && !match->is_group()) { - ++match.pos_; - } - - if(match.pos_.level() > pos_.level()) { - scopes_.push(pos_.undo_point()); - pos_ = std::move(match.pos_); - } - else if(match.pos_.level() < pos_.level()) { - return_to_level(match.pos_.level()); - } - else { - pos_ = std::move(match.pos_); - } - } - posAfterLastMatch_ = pos_; - } - else { - if(match.pos_.level() < pos_.level()) { - return_to_level(match.pos_.level()); - } - posAfterLastMatch_ = pos_; - } - repeatGroupContinues_ = repeat_group_continues(); - } - -private: - //----------------------------------------------------- - bool is_last_in_current_scope(const dfs_traverser& pos) const - { - if(scopes_.empty()) return pos.is_last_in_path(); - //check if we would leave the current scope on ++ - auto p = pos; - ++p; - return p.level() < scopes_.top().level(); - } - - //----------------------------------------------------- - void check_repeat_group_start(const scoped_dfs_traverser& newMatch) - { - const auto newrg = newMatch.innermost_repeat_group(); - if(!newrg) { - repeatGroupStarted_ = false; - } - else if(lastMatch_.innermost_repeat_group() != newrg) { - repeatGroupStarted_ = true; - } - else if(!repeatGroupContinues_ || !newMatch.repeatGroupContinues_) { - repeatGroupStarted_ = true; - } - else { - //special case: repeat group is outermost group - //=> we can never really 'leave' and 'reenter' it - //but if the current scope is the first element, then we are - //conceptually at a position 'before' the group - repeatGroupStarted_ = scopes_.empty() || ( - newrg == pos_.root() && - scopes_.top().param() == &(*pos_.root()->begin()) ); - } - repeatGroupContinues_ = repeatGroupStarted_; - } - - //----------------------------------------------------- - bool repeat_group_continues() const - { - if(!repeatGroupContinues_) return false; - const auto curRepGroup = pos_.innermost_repeat_group(); - if(!curRepGroup) return false; - if(curRepGroup != lastMatch_.innermost_repeat_group()) return false; - if(!posAfterLastMatch_) return false; - return true; - } - - //----------------------------------------------------- - void check_if_left_scope() - { - if(posAfterLastMatch_) { - if(pos_.level() < posAfterLastMatch_.level()) { - while(!scopes_.empty() && scopes_.top().level() >= pos_.level()) { - pos_.undo(scopes_.top()); - scopes_.pop(); - } - posAfterLastMatch_.invalidate(); - } - } - while(!scopes_.empty() && scopes_.top().level() > pos_.level()) { - pos_.undo(scopes_.top()); - scopes_.pop(); - } - repeatGroupContinues_ = repeat_group_continues(); - } - - //----------------------------------------------------- - void return_to_outermost_scope() - { - posAfterLastMatch_.invalidate(); - - if(scopes_.empty()) { - pos_.invalidate(); - repeatGroupContinues_ = false; - return; - } - - while(!scopes_.empty() && (!pos_ || pos_.level() >= 1)) { - pos_.undo(scopes_.top()); - scopes_.pop(); - } - while(!scopes_.empty()) scopes_.pop(); - - repeatGroupContinues_ = repeat_group_continues(); - } - - //----------------------------------------------------- - void return_to_level(int level) - { - if(pos_.level() <= level) return; - while(!scopes_.empty() && pos_.level() > level) { - pos_.undo(scopes_.top()); - scopes_.pop(); - } - }; - - dfs_traverser pos_; - dfs_traverser lastMatch_; - dfs_traverser posAfterLastMatch_; - std::stack scopes_; - bool ignoreBlocks_ = false; - bool repeatGroupStarted_ = false; - bool repeatGroupContinues_ = false; -}; - - - - -/***************************************************************************** - * - * some parameter property predicates - * - *****************************************************************************/ -struct select_all { - bool operator () (const parameter&) const noexcept { return true; } -}; - -struct select_flags { - bool operator () (const parameter& p) const noexcept { - return !p.flags().empty(); - } -}; - -struct select_values { - bool operator () (const parameter& p) const noexcept { - return p.flags().empty(); - } -}; - - - -/*************************************************************************//** - * - * @brief result of a matching operation - * - *****************************************************************************/ -class match_t { -public: - using size_type = arg_string::size_type; - - match_t() = default; - - match_t(arg_string s, scoped_dfs_traverser p): - str_{std::move(s)}, pos_{std::move(p)} - {} - - size_type length() const noexcept { return str_.size(); } - - const arg_string& str() const noexcept { return str_; } - const scoped_dfs_traverser& pos() const noexcept { return pos_; } - - explicit operator bool() const noexcept { return bool(pos_); } - -private: - arg_string str_; - scoped_dfs_traverser pos_; -}; - - - -/*************************************************************************//** - * - * @brief finds the first parameter that matches a given string; - * candidate parameters are traversed using a scoped DFS traverser - * - *****************************************************************************/ -template -match_t -full_match(scoped_dfs_traverser pos, const arg_string& arg, - const ParamSelector& select) -{ - while(pos) { - if(pos->is_param()) { - const auto& param = pos->as_param(); - if(select(param)) { - const auto match = param.match(arg); - if(match && match.length() == arg.size()) { - return match_t{arg, std::move(pos)}; - } - } - } - ++pos; - } - return match_t{}; -} - - - -/*************************************************************************//** - * - * @brief finds the first parameter that matches any (non-empty) prefix - * of a given string; - * candidate parameters are traversed using a scoped DFS traverser - * - *****************************************************************************/ -template -match_t -longest_prefix_match(scoped_dfs_traverser pos, const arg_string& arg, - const ParamSelector& select) -{ - match_t longest; - - while(pos) { - if(pos->is_param()) { - const auto& param = pos->as_param(); - if(select(param)) { - auto match = param.match(arg); - if(match.prefix()) { - if(match.length() == arg.size()) { - return match_t{arg, std::move(pos)}; - } - else if(match.length() > longest.length()) { - longest = match_t{arg.substr(match.at(), match.length()), - pos}; - } - } - } - } - ++pos; - } - return longest; -} - - - -/*************************************************************************//** - * - * @brief finds the first parameter that partially matches a given string; - * candidate parameters are traversed using a scoped DFS traverser - * - *****************************************************************************/ -template -match_t -partial_match(scoped_dfs_traverser pos, const arg_string& arg, - const ParamSelector& select) -{ - while(pos) { - if(pos->is_param()) { - const auto& param = pos->as_param(); - if(select(param)) { - const auto match = param.match(arg); - if(match) { - return match_t{arg.substr(match.at(), match.length()), - std::move(pos)}; - } - } - } - ++pos; - } - return match_t{}; -} - -} //namespace detail - - - - - - -/***************************************************************//** - * - * @brief default command line arguments parser - * - *******************************************************************/ -class parser -{ -public: - using dfs_traverser = group::depth_first_traverser; - using scoped_dfs_traverser = detail::scoped_dfs_traverser; - - - /*****************************************************//** - * @brief arg -> parameter mapping - *********************************************************/ - class arg_mapping { - public: - friend class parser; - - explicit - arg_mapping(arg_index idx, arg_string s, - const dfs_traverser& match) - : - index_{idx}, arg_{std::move(s)}, match_{match}, - repeat_{0}, startsRepeatGroup_{false}, - blocked_{false}, conflict_{false} - {} - - explicit - arg_mapping(arg_index idx, arg_string s) : - index_{idx}, arg_{std::move(s)}, match_{}, - repeat_{0}, startsRepeatGroup_{false}, - blocked_{false}, conflict_{false} - {} - - arg_index index() const noexcept { return index_; } - const arg_string& arg() const noexcept { return arg_; } - - const parameter* param() const noexcept { - return match_ && match_->is_param() - ? &(match_->as_param()) : nullptr; - } - - std::size_t repeat() const noexcept { return repeat_; } - - bool blocked() const noexcept { return blocked_; } - bool conflict() const noexcept { return conflict_; } - - bool bad_repeat() const noexcept { - if(!param()) return false; - return repeat_ > 0 && !param()->repeatable() - && !match_.innermost_repeat_group(); - } - - bool any_error() const noexcept { - return !match_ || blocked() || conflict() || bad_repeat(); - } - - private: - arg_index index_; - arg_string arg_; - dfs_traverser match_; - std::size_t repeat_; - bool startsRepeatGroup_; - bool blocked_; - bool conflict_; - }; - - /*****************************************************//** - * @brief references a non-matched, required parameter - *********************************************************/ - class missing_event { - public: - explicit - missing_event(const parameter* p, arg_index after): - param_{p}, aftIndex_{after} - {} - - const parameter* param() const noexcept { return param_; } - - arg_index after_index() const noexcept { return aftIndex_; } - - private: - const parameter* param_; - arg_index aftIndex_; - }; - - //----------------------------------------------------- - using missing_events = std::vector; - using arg_mappings = std::vector; - - -private: - struct miss_candidate { - miss_candidate(dfs_traverser p, arg_index idx, - bool firstInRepeatGroup = false): - pos{std::move(p)}, index{idx}, - startsRepeatGroup{firstInRepeatGroup} - {} - - dfs_traverser pos; - arg_index index; - bool startsRepeatGroup; - }; - using miss_candidates = std::vector; - - -public: - //--------------------------------------------------------------- - /** @brief initializes parser with a command line interface - * @param offset = argument index offset used for reports - * */ - explicit - parser(const group& root, arg_index offset = 0): - root_{&root}, pos_{root}, - index_{offset-1}, eaten_{0}, - args_{}, missCand_{}, blocked_{false} - { - for_each_potential_miss(dfs_traverser{root}, - [this](const dfs_traverser& p){ - missCand_.emplace_back(p, index_); - }); - } - - - //--------------------------------------------------------------- - /** @brief processes one command line argument */ - bool operator() (const arg_string& arg) - { - ++eaten_; - ++index_; - - if(!valid()) return false; - - if(!blocked_ && try_match(arg)) return true; - - if(try_match_blocked(arg)) return false; - - //skipping of blocking & required patterns is not allowed - if(!blocked_ && !pos_.matched() && pos_->required() && pos_->blocking()) { - blocked_ = true; - } - - add_nomatch(arg); - return false; - } - - - //--------------------------------------------------------------- - /** @brief returns range of argument -> parameter mappings */ - const arg_mappings& args() const { - return args_; - } - - /** @brief returns list of missing events */ - missing_events missed() const { - missing_events misses; - misses.reserve(missCand_.size()); - for(auto i = missCand_.begin(); i != missCand_.end(); ++i) { - misses.emplace_back(&(i->pos->as_param()), i->index); - } - return misses; - } - - /** @brief returns number of processed command line arguments */ - arg_index parse_count() const noexcept { return eaten_; } - - /** @brief returns false if previously processed command line arguments - * lead to an invalid / inconsistent parsing result - */ - bool valid() const noexcept { return bool(pos_); } - - /** @brief returns false if previously processed command line arguments - * lead to an invalid / inconsistent parsing result - */ - explicit operator bool() const noexcept { return valid(); } - - -private: - //--------------------------------------------------------------- - using match_t = detail::match_t; - - - //--------------------------------------------------------------- - /** @brief try to match argument with unreachable parameter */ - bool try_match_blocked(const arg_string& arg) - { - //try to match ahead (using temporary parser) - if(pos_) { - auto ahead = *this; - if(try_match_blocked(std::move(ahead), arg)) return true; - } - - //try to match from the beginning (using temporary parser) - if(root_) { - parser all{*root_, index_+1}; - if(try_match_blocked(std::move(all), arg)) return true; - } - - return false; - } - - //--------------------------------------------------------------- - bool try_match_blocked(parser&& parse, const arg_string& arg) - { - const auto nold = int(parse.args_.size()); - - parse.pos_.ignore_blocking(true); - - if(!parse.try_match(arg)) return false; - - for(auto i = parse.args_.begin() + nold; i != parse.args_.end(); ++i) { - args_.push_back(*i); - args_.back().blocked_ = true; - } - return true; - } - - //--------------------------------------------------------------- - /** @brief try to find a parameter/pattern that matches 'arg' */ - bool try_match(const arg_string& arg) - { - //match greedy parameters before everything else - if(pos_->is_param() && pos_->blocking() && pos_->as_param().greedy()) { - const auto match = pos_->as_param().match(arg); - if(match && match.length() == arg.size()) { - add_match(detail::match_t{arg,pos_}); - return true; - } - } - - //try flags first (alone, joinable or strict sequence) - if(try_match_full(arg, detail::select_flags{})) return true; - if(try_match_joined_flags(arg)) return true; - if(try_match_joined_sequence(arg, detail::select_flags{})) return true; - //try value params (alone or strict sequence) - if(try_match_full(arg, detail::select_values{})) return true; - if(try_match_joined_sequence(arg, detail::select_all{})) return true; - //try joinable params + values in any order - if(try_match_joined_params(arg)) return true; - return false; - } - - //--------------------------------------------------------------- - /** - * @brief try to match full argument - * @param select : predicate that candidate parameters must satisfy - */ - template - bool try_match_full(const arg_string& arg, const ParamSelector& select) - { - auto match = detail::full_match(pos_, arg, select); - if(!match) return false; - add_match(match); - return true; - } - - //--------------------------------------------------------------- - /** - * @brief try to match argument as blocking sequence of parameters - * @param select : predicate that a parameter matching the prefix of - * 'arg' must satisfy - */ - template - bool try_match_joined_sequence(arg_string arg, - const ParamSelector& acceptFirst) - { - auto fstMatch = detail::longest_prefix_match(pos_, arg, acceptFirst); - - if(!fstMatch) return false; - - if(fstMatch.str().size() == arg.size()) { - add_match(fstMatch); - return true; - } - - if(!fstMatch.pos()->blocking()) return false; - - auto pos = fstMatch.pos(); - pos.ignore_blocking(true); - const auto parent = &pos.parent(); - if(!pos->repeatable()) ++pos; - - arg.erase(0, fstMatch.str().size()); - std::vector matches { std::move(fstMatch) }; - - while(!arg.empty() && pos && - pos->blocking() && pos->is_param() && - (&pos.parent() == parent)) - { - auto match = pos->as_param().match(arg); - - if(match.prefix()) { - matches.emplace_back(arg.substr(0,match.length()), pos); - arg.erase(0, match.length()); - if(!pos->repeatable()) ++pos; - } - else { - if(!pos->repeatable()) return false; - ++pos; - } - - } - //if arg not fully covered => discard temporary matches - if(!arg.empty() || matches.empty()) return false; - - for(const auto& m : matches) add_match(m); - return true; - } - - //----------------------------------------------------- - /** @brief try to match 'arg' as a concatenation of joinable flags */ - bool try_match_joined_flags(const arg_string& arg) - { - return find_join_group(pos_, [&](const group& g) { - return try_match_joined(g, arg, detail::select_flags{}, - g.common_flag_prefix()); - }); - } - - //--------------------------------------------------------------- - /** @brief try to match 'arg' as a concatenation of joinable parameters */ - bool try_match_joined_params(const arg_string& arg) - { - return find_join_group(pos_, [&](const group& g) { - return try_match_joined(g, arg, detail::select_all{}); - }); - } - - //----------------------------------------------------- - /** @brief try to match 'arg' as concatenation of joinable parameters - * that are all contained within one group - */ - template - bool try_match_joined(const group& joinGroup, arg_string arg, - const ParamSelector& select, - const arg_string& prefix = "") - { - //temporary parser with 'joinGroup' as top-level group - parser parse {joinGroup}; - //records temporary matches - std::vector matches; - - while(!arg.empty()) { - auto match = detail::longest_prefix_match(parse.pos_, arg, select); - - if(!match) return false; - - arg.erase(0, match.str().size()); - //make sure prefix is always present after the first match - //so that, e.g., flags "-a" and "-b" will be found in "-ab" - if(!arg.empty() && !prefix.empty() && arg.find(prefix) != 0 && - prefix != match.str()) - { - arg.insert(0,prefix); - } - - parse.add_match(match); - matches.push_back(std::move(match)); - } - - if(!arg.empty() || matches.empty()) return false; - - if(!parse.missCand_.empty()) return false; - for(const auto& a : parse.args_) if(a.any_error()) return false; - - //replay matches onto *this - for(const auto& m : matches) add_match(m); - return true; - } - - //----------------------------------------------------- - template - bool find_join_group(const scoped_dfs_traverser& start, - const GroupSelector& accept) const - { - if(start && start.parent().joinable()) { - const auto& g = start.parent(); - if(accept(g)) return true; - return false; - } - - auto pos = start; - while(pos) { - if(pos->is_group() && pos->as_group().joinable()) { - const auto& g = pos->as_group(); - if(accept(g)) return true; - pos.next_sibling(); - } - else { - ++pos; - } - } - return false; - } - - - //--------------------------------------------------------------- - void add_nomatch(const arg_string& arg) { - args_.emplace_back(index_, arg); - } - - - //--------------------------------------------------------------- - void add_match(const match_t& match) - { - const auto& pos = match.pos(); - if(!pos || !pos->is_param()) return; - - pos_.next_after_match(pos); - - arg_mapping newArg{index_, match.str(), pos.base()}; - newArg.repeat_ = occurrences_of(&pos->as_param()); - newArg.conflict_ = check_conflicts(pos.base()); - newArg.startsRepeatGroup_ = pos_.start_of_repeat_group(); - args_.push_back(std::move(newArg)); - - add_miss_candidates_after(pos); - clean_miss_candidates_for(pos.base()); - discard_alternative_miss_candidates(pos.base()); - - } - - //----------------------------------------------------- - bool check_conflicts(const dfs_traverser& match) - { - if(pos_.start_of_repeat_group()) return false; - bool conflict = false; - for(const auto& m : match.stack()) { - if(m.parent->exclusive()) { - for(auto i = args_.rbegin(); i != args_.rend(); ++i) { - if(!i->blocked()) { - for(const auto& c : i->match_.stack()) { - //sibling within same exclusive group => conflict - if(c.parent == m.parent && c.cur != m.cur) { - conflict = true; - i->conflict_ = true; - } - } - } - //check for conflicts only within current repeat cycle - if(i->startsRepeatGroup_) break; - } - } - } - return conflict; - } - - //----------------------------------------------------- - void clean_miss_candidates_for(const dfs_traverser& match) - { - auto i = std::find_if(missCand_.rbegin(), missCand_.rend(), - [&](const miss_candidate& m) { - return &(*m.pos) == &(*match); - }); - - if(i != missCand_.rend()) { - missCand_.erase(prev(i.base())); - } - } - - //----------------------------------------------------- - void discard_alternative_miss_candidates(const dfs_traverser& match) - { - if(missCand_.empty()) return; - //find out, if miss candidate is sibling of one of the same - //alternative groups that the current match is a member of - //if so, we can discard the miss - - //go through all exclusive groups of matching pattern - for(const auto& m : match.stack()) { - if(m.parent->exclusive()) { - for(auto i = int(missCand_.size())-1; i >= 0; --i) { - bool removed = false; - for(const auto& c : missCand_[i].pos.stack()) { - //sibling within same exclusive group => discard - if(c.parent == m.parent && c.cur != m.cur) { - missCand_.erase(missCand_.begin() + i); - if(missCand_.empty()) return; - removed = true; - break; - } - } - //remove miss candidates only within current repeat cycle - if(i > 0 && removed) { - if(missCand_[i-1].startsRepeatGroup) break; - } else { - if(missCand_[i].startsRepeatGroup) break; - } - } - } - } - } - - //----------------------------------------------------- - void add_miss_candidates_after(const scoped_dfs_traverser& match) - { - auto npos = match.base(); - if(npos.is_alternative()) npos.skip_alternatives(); - ++npos; - //need to add potential misses if: - //either new repeat group was started - const auto newRepGroup = match.innermost_repeat_group(); - if(newRepGroup) { - if(pos_.start_of_repeat_group()) { - for_each_potential_miss(std::move(npos), - [&,this](const dfs_traverser& pos) { - //only add candidates within repeat group - if(newRepGroup == pos.innermost_repeat_group()) { - missCand_.emplace_back(pos, index_, true); - } - }); - } - } - //... or an optional blocking param was hit - else if(match->blocking() && !match->required() && - npos.level() >= match.base().level()) - { - for_each_potential_miss(std::move(npos), - [&,this](const dfs_traverser& pos) { - //only add new candidates - if(std::find_if(missCand_.begin(), missCand_.end(), - [&](const miss_candidate& c){ - return &(*c.pos) == &(*pos); - }) == missCand_.end()) - { - missCand_.emplace_back(pos, index_); - } - }); - } - - } - - //----------------------------------------------------- - template - static void - for_each_potential_miss(dfs_traverser pos, Action&& action) - { - const auto level = pos.level(); - while(pos && pos.level() >= level) { - if(pos->is_group() ) { - const auto& g = pos->as_group(); - if(g.all_optional() || (g.exclusive() && g.any_optional())) { - pos.next_sibling(); - } else { - ++pos; - } - } else { //param - if(pos->required()) { - action(pos); - ++pos; - } else if(pos->blocking()) { //optional + blocking - pos.next_after_siblings(); - } else { - ++pos; - } - } - } - } - - - //--------------------------------------------------------------- - std::size_t occurrences_of(const parameter* p) const - { - if(!p) return 0; - - auto i = std::find_if(args_.rbegin(), args_.rend(), - [p](const arg_mapping& a){ return a.param() == p; }); - - if(i != args_.rend()) return i->repeat() + 1; - return 0; - } - - - //--------------------------------------------------------------- - const group* root_; - scoped_dfs_traverser pos_; - arg_index index_; - arg_index eaten_; - arg_mappings args_; - miss_candidates missCand_; - bool blocked_; -}; - - - - -/*************************************************************************//** - * - * @brief contains argument -> parameter mappings - * and missing parameters - * - *****************************************************************************/ -class parsing_result -{ -public: - using arg_mapping = parser::arg_mapping; - using arg_mappings = parser::arg_mappings; - using missing_event = parser::missing_event; - using missing_events = parser::missing_events; - using iterator = arg_mappings::const_iterator; - - //----------------------------------------------------- - /** @brief default: empty result */ - parsing_result() = default; - - parsing_result(arg_mappings arg2param, missing_events misses): - arg2param_{std::move(arg2param)}, missing_{std::move(misses)} - {} - - //----------------------------------------------------- - /** @brief returns number of arguments that could not be mapped to - * a parameter - */ - arg_mappings::size_type - unmapped_args_count() const noexcept { - return std::count_if(arg2param_.begin(), arg2param_.end(), - [](const arg_mapping& a){ return !a.param(); }); - } - - /** @brief returns if any argument could only be matched by an - * unreachable parameter - */ - bool any_blocked() const noexcept { - return std::any_of(arg2param_.begin(), arg2param_.end(), - [](const arg_mapping& a){ return a.blocked(); }); - } - - /** @brief returns if any argument matched more than one parameter - * that were mutually exclusive */ - bool any_conflict() const noexcept { - return std::any_of(arg2param_.begin(), arg2param_.end(), - [](const arg_mapping& a){ return a.conflict(); }); - } - - /** @brief returns if any parameter matched repeatedly although - * it was not allowed to */ - bool any_bad_repeat() const noexcept { - return std::any_of(arg2param_.begin(), arg2param_.end(), - [](const arg_mapping& a){ return a.bad_repeat(); }); - } - - /** @brief returns true if any parsing error / violation of the - * command line interface definition occurred */ - bool any_error() const noexcept { - return unmapped_args_count() > 0 || !missing().empty() || - any_blocked() || any_conflict() || any_bad_repeat(); - } - - /** @brief returns true if no parsing error / violation of the - * command line interface definition occurred */ - explicit operator bool() const noexcept { return !any_error(); } - - /** @brief access to range of missing parameter match events */ - const missing_events& missing() const noexcept { return missing_; } - - /** @brief returns non-mutating iterator to position of - * first argument -> parameter mapping */ - iterator begin() const noexcept { return arg2param_.begin(); } - /** @brief returns non-mutating iterator to position one past the - * last argument -> parameter mapping */ - iterator end() const noexcept { return arg2param_.end(); } - -private: - //----------------------------------------------------- - arg_mappings arg2param_; - missing_events missing_; -}; - - - - -namespace detail { -namespace { - -/*************************************************************************//** - * - * @brief correct some common problems - * does not - and MUST NOT - change the number of arguments - * (no insertions or deletions allowed) - * - *****************************************************************************/ -void sanitize_args(arg_list& args) -{ - //e.g. {"-o12", ".34"} -> {"-o", "12.34"} - - if(args.empty()) return; - - for(auto i = begin(args)+1; i != end(args); ++i) { - if(i != begin(args) && i->size() > 1 && - i->find('.') == 0 && std::isdigit((*i)[1]) ) - { - //find trailing digits in previous arg - using std::prev; - auto& prv = *prev(i); - auto fstDigit = std::find_if_not(prv.rbegin(), prv.rend(), - [](arg_string::value_type c){ - return std::isdigit(c); - }).base(); - - //handle leading sign - if(fstDigit > prv.begin() && - (*prev(fstDigit) == '+' || *prev(fstDigit) == '-')) - { - --fstDigit; - } - - //prepend digits from previous arg - i->insert(begin(*i), fstDigit, end(prv)); - - //erase digits in previous arg - prv.erase(fstDigit, end(prv)); - } - } -} - - - -/*************************************************************************//** - * - * @brief executes actions based on a parsing result - * - *****************************************************************************/ -void execute_actions(const parsing_result& res) -{ - for(const auto& m : res) { - if(m.param()) { - const auto& param = *(m.param()); - - if(m.repeat() > 0) param.notify_repeated(m.index()); - if(m.blocked()) param.notify_blocked(m.index()); - if(m.conflict()) param.notify_conflict(m.index()); - //main action - if(!m.any_error()) param.execute_actions(m.arg()); - } - } - - for(auto m : res.missing()) { - if(m.param()) m.param()->notify_missing(m.after_index()); - } -} - - - -/*************************************************************************//** - * - * @brief parses input args - * - *****************************************************************************/ -static parsing_result -parse_args(const arg_list& args, const group& cli, - arg_index offset = 0) -{ - //parse args and store unrecognized arg indices - parser parse{cli, offset}; - for(const auto& arg : args) { - parse(arg); - if(!parse.valid()) break; - } - - return parsing_result{parse.args(), parse.missed()}; -} - -/*************************************************************************//** - * - * @brief parses input args & executes actions - * - *****************************************************************************/ -static parsing_result -parse_and_execute(const arg_list& args, const group& cli, - arg_index offset = 0) -{ - auto result = parse_args(args, cli, offset); - - execute_actions(result); - - return result; -} - -} //anonymous namespace -} // namespace detail - - - - -/*************************************************************************//** - * - * @brief parses vector of arg strings and executes actions - * - *****************************************************************************/ -inline parsing_result -parse(arg_list args, const group& cli) -{ - detail::sanitize_args(args); - return detail::parse_and_execute(args, cli); -} - - -/*************************************************************************//** - * - * @brief parses initializer_list of C-style arg strings and executes actions - * - *****************************************************************************/ -inline parsing_result -parse(std::initializer_list arglist, const group& cli) -{ - arg_list args; - args.reserve(arglist.size()); - for(auto a : arglist) { - args.push_back(a); - } - - return parse(std::move(args), cli); -} - - -/*************************************************************************//** - * - * @brief parses range of arg strings and executes actions - * - *****************************************************************************/ -template -inline parsing_result -parse(InputIterator first, InputIterator last, const group& cli) -{ - return parse(arg_list(first,last), cli); -} - - -/*************************************************************************//** - * - * @brief parses the standard array of command line arguments; omits argv[0] - * - *****************************************************************************/ -inline parsing_result -parse(const int argc, char* argv[], const group& cli, arg_index offset = 1) -{ - arg_list args; - if(offset < argc) args.assign(argv+offset, argv+argc); - detail::sanitize_args(args); - return detail::parse_and_execute(args, cli, offset); -} - - - - - - -/*************************************************************************//** - * - * @brief filter predicate for parameters and groups; - * Can be used to limit documentation generation to parameter subsets. - * - *****************************************************************************/ -class param_filter -{ -public: - /** @brief only allow parameters with given prefix */ - param_filter& prefix(const arg_string& p) noexcept { - prefix_ = p; return *this; - } - /** @brief only allow parameters with given prefix */ - param_filter& prefix(arg_string&& p) noexcept { - prefix_ = std::move(p); return *this; - } - const arg_string& prefix() const noexcept { return prefix_; } - - /** @brief only allow parameters with given requirement status */ - param_filter& required(tri t) noexcept { required_ = t; return *this; } - tri required() const noexcept { return required_; } - - /** @brief only allow parameters with given blocking status */ - param_filter& blocking(tri t) noexcept { blocking_ = t; return *this; } - tri blocking() const noexcept { return blocking_; } - - /** @brief only allow parameters with given repeatable status */ - param_filter& repeatable(tri t) noexcept { repeatable_ = t; return *this; } - tri repeatable() const noexcept { return repeatable_; } - - /** @brief only allow parameters with given docstring status */ - param_filter& has_doc(tri t) noexcept { hasDoc_ = t; return *this; } - tri has_doc() const noexcept { return hasDoc_; } - - - /** @brief returns true, if parameter satisfies all filters */ - bool operator() (const parameter& p) const noexcept { - if(!prefix_.empty()) { - if(!std::any_of(p.flags().begin(), p.flags().end(), - [&](const arg_string& flag){ - return str::has_prefix(flag, prefix_); - })) return false; - } - if(required() != p.required()) return false; - if(blocking() != p.blocking()) return false; - if(repeatable() != p.repeatable()) return false; - if(has_doc() != !p.doc().empty()) return false; - return true; - } - -private: - arg_string prefix_; - tri required_ = tri::either; - tri blocking_ = tri::either; - tri repeatable_ = tri::either; - tri hasDoc_ = tri::yes; -}; - - - - - - -/*************************************************************************//** - * - * @brief documentation formatting options - * - *****************************************************************************/ -class doc_formatting -{ -public: - using string = doc_string; - - /** @brief same as 'first_column' */ -#if __cplusplus >= 201402L - [[deprecated]] -#endif - doc_formatting& start_column(int col) { return first_column(col); } -#if __cplusplus >= 201402L - [[deprecated]] -#endif - int start_column() const noexcept { return first_column(); } - - /** @brief determines column where documentation printing starts */ - doc_formatting& - first_column(int col) { - //limit to [0,last_column] but push doc_column to the right if necessary - if(col < 0) col = 0; - else if(col > last_column()) col = last_column(); - if(col > doc_column()) doc_column(first_column()); - firstCol_ = col; - return *this; - } - int first_column() const noexcept { - return firstCol_; - } - - /** @brief determines column where docstrings start */ - doc_formatting& - doc_column(int col) { - //limit to [first_column,last_column] - if(col < 0) col = 0; - else if(col < first_column()) col = first_column(); - else if(col > last_column()) col = last_column(); - docCol_ = col; - return *this; - } - int doc_column() const noexcept { - return docCol_; - } - - /** @brief determines column that no documentation text must exceed; - * (text should be wrapped appropriately after this column) - */ - doc_formatting& - last_column(int col) { - //limit to [first_column,oo] but push doc_column to the left if necessary - if(col < first_column()) col = first_column(); - if(col < doc_column()) doc_column(col); - lastCol_ = col; - return *this; - } - - int last_column() const noexcept { - return lastCol_; - } - - /** @brief determines indent of documentation lines - * for children of a documented group */ - doc_formatting& indent_size(int indent) { indentSize_ = indent; return *this; } - int indent_size() const noexcept { return indentSize_; } - - /** @brief determines string to be used - * if a parameter has no flags and no label */ - doc_formatting& empty_label(const string& label) { - emptyLabel_ = label; - return *this; - } - const string& empty_label() const noexcept { return emptyLabel_; } - - /** @brief determines string for separating parameters */ - doc_formatting& param_separator(const string& sep) { - paramSep_ = sep; - return *this; - } - const string& param_separator() const noexcept { return paramSep_; } - - /** @brief determines string for separating groups (in usage lines) */ - doc_formatting& group_separator(const string& sep) { - groupSep_ = sep; - return *this; - } - const string& group_separator() const noexcept { return groupSep_; } - - /** @brief determines string for separating alternative parameters */ - doc_formatting& alternative_param_separator(const string& sep) { - altParamSep_ = sep; - return *this; - } - const string& alternative_param_separator() const noexcept { return altParamSep_; } - - /** @brief determines string for separating alternative groups */ - doc_formatting& alternative_group_separator(const string& sep) { - altGroupSep_ = sep; - return *this; - } - const string& alternative_group_separator() const noexcept { return altGroupSep_; } - - /** @brief determines string for separating flags of the same parameter */ - doc_formatting& flag_separator(const string& sep) { - flagSep_ = sep; - return *this; - } - const string& flag_separator() const noexcept { return flagSep_; } - - /** @brief determines strings surrounding parameter labels */ - doc_formatting& - surround_labels(const string& prefix, const string& postfix) { - labelPre_ = prefix; - labelPst_ = postfix; - return *this; - } - const string& label_prefix() const noexcept { return labelPre_; } - const string& label_postfix() const noexcept { return labelPst_; } - - /** @brief determines strings surrounding optional parameters/groups */ - doc_formatting& - surround_optional(const string& prefix, const string& postfix) { - optionPre_ = prefix; - optionPst_ = postfix; - return *this; - } - const string& optional_prefix() const noexcept { return optionPre_; } - const string& optional_postfix() const noexcept { return optionPst_; } - - /** @brief determines strings surrounding repeatable parameters/groups */ - doc_formatting& - surround_repeat(const string& prefix, const string& postfix) { - repeatPre_ = prefix; - repeatPst_ = postfix; - return *this; - } - const string& repeat_prefix() const noexcept { return repeatPre_; } - const string& repeat_postfix() const noexcept { return repeatPst_; } - - /** @brief determines strings surrounding exclusive groups */ - doc_formatting& - surround_alternatives(const string& prefix, const string& postfix) { - alternPre_ = prefix; - alternPst_ = postfix; - return *this; - } - const string& alternatives_prefix() const noexcept { return alternPre_; } - const string& alternatives_postfix() const noexcept { return alternPst_; } - - /** @brief determines strings surrounding alternative flags */ - doc_formatting& - surround_alternative_flags(const string& prefix, const string& postfix) { - alternFlagPre_ = prefix; - alternFlagPst_ = postfix; - return *this; - } - const string& alternative_flags_prefix() const noexcept { return alternFlagPre_; } - const string& alternative_flags_postfix() const noexcept { return alternFlagPst_; } - - /** @brief determines strings surrounding non-exclusive groups */ - doc_formatting& - surround_group(const string& prefix, const string& postfix) { - groupPre_ = prefix; - groupPst_ = postfix; - return *this; - } - const string& group_prefix() const noexcept { return groupPre_; } - const string& group_postfix() const noexcept { return groupPst_; } - - /** @brief determines strings surrounding joinable groups */ - doc_formatting& - surround_joinable(const string& prefix, const string& postfix) { - joinablePre_ = prefix; - joinablePst_ = postfix; - return *this; - } - const string& joinable_prefix() const noexcept { return joinablePre_; } - const string& joinable_postfix() const noexcept { return joinablePst_; } - - /** @brief determines maximum number of flags per parameter to be printed - * in detailed parameter documentation lines */ - doc_formatting& max_flags_per_param_in_doc(int max) { - maxAltInDocs_ = max > 0 ? max : 0; - return *this; - } - int max_flags_per_param_in_doc() const noexcept { return maxAltInDocs_; } - - /** @brief determines maximum number of flags per parameter to be printed - * in usage lines */ - doc_formatting& max_flags_per_param_in_usage(int max) { - maxAltInUsage_ = max > 0 ? max : 0; - return *this; - } - int max_flags_per_param_in_usage() const noexcept { return maxAltInUsage_; } - - /** @brief determines number of empty rows after one single-line - * documentation entry */ - doc_formatting& line_spacing(int lines) { - lineSpc_ = lines > 0 ? lines : 0; - return *this; - } - int line_spacing() const noexcept { return lineSpc_; } - - /** @brief determines number of empty rows before and after a paragraph; - * a paragraph is defined by a documented group or if - * a parameter documentation entry used more than one line */ - doc_formatting& paragraph_spacing(int lines) { - paragraphSpc_ = lines > 0 ? lines : 0; - return *this; - } - int paragraph_spacing() const noexcept { return paragraphSpc_; } - - /** @brief determines if alternative flags with a common prefix should - * be printed in a merged fashion */ - doc_formatting& merge_alternative_flags_with_common_prefix(bool yes = true) { - mergeAltCommonPfx_ = yes; - return *this; - } - bool merge_alternative_flags_with_common_prefix() const noexcept { - return mergeAltCommonPfx_; - } - - /** @brief determines if joinable flags with a common prefix should - * be printed in a merged fashion */ - doc_formatting& merge_joinable_with_common_prefix(bool yes = true) { - mergeJoinableCommonPfx_ = yes; - return *this; - } - bool merge_joinable_with_common_prefix() const noexcept { - return mergeJoinableCommonPfx_; - } - - /** @brief determines if children of exclusive groups should be printed - * on individual lines if the exceed 'alternatives_min_split_size' - */ - doc_formatting& split_alternatives(bool yes = true) { - splitTopAlt_ = yes; - return *this; - } - bool split_alternatives() const noexcept { - return splitTopAlt_; - } - - /** @brief determines how many children exclusive groups can have before - * their children are printed on individual usage lines */ - doc_formatting& alternatives_min_split_size(int size) { - groupSplitSize_ = size > 0 ? size : 0; - return *this; - } - int alternatives_min_split_size() const noexcept { return groupSplitSize_; } - - /** @brief determines whether to ignore new line characters in docstrings - */ - doc_formatting& ignore_newline_chars(bool yes = true) { - ignoreNewlines_ = yes; - return *this; - } - bool ignore_newline_chars() const noexcept { - return ignoreNewlines_; - } - -private: - string paramSep_ = string(" "); - string groupSep_ = string(" "); - string altParamSep_ = string("|"); - string altGroupSep_ = string(" | "); - string flagSep_ = string(", "); - string labelPre_ = string("<"); - string labelPst_ = string(">"); - string optionPre_ = string("["); - string optionPst_ = string("]"); - string repeatPre_ = string(""); - string repeatPst_ = string("..."); - string groupPre_ = string("("); - string groupPst_ = string(")"); - string alternPre_ = string("("); - string alternPst_ = string(")"); - string alternFlagPre_ = string(""); - string alternFlagPst_ = string(""); - string joinablePre_ = string("("); - string joinablePst_ = string(")"); - string emptyLabel_ = string(""); - int firstCol_ = 8; - int docCol_ = 20; - int lastCol_ = 100; - int indentSize_ = 4; - int maxAltInUsage_ = 1; - int maxAltInDocs_ = 32; - int lineSpc_ = 0; - int paragraphSpc_ = 1; - int groupSplitSize_ = 3; - bool splitTopAlt_ = true; - bool mergeAltCommonPfx_ = false; - bool mergeJoinableCommonPfx_ = true; - bool ignoreNewlines_ = false; -}; - - - -namespace detail { - -/*************************************************************************//** - * - * @brief stream decorator - * that applies formatting like line wrapping - * - *****************************************************************************/ -template -class formatting_ostream -{ -public: - using string_type = StringT; - using size_type = typename string_type::size_type; - using char_type = typename string_type::value_type; - - formatting_ostream(OStream& os): - os_(os), - curCol_{0}, firstCol_{0}, lastCol_{100}, - hangingIndent_{0}, paragraphSpacing_{0}, paragraphSpacingThreshold_{2}, - curBlankLines_{0}, curParagraphLines_{1}, - totalNonBlankLines_{0}, - ignoreInputNls_{false} - {} - - - //--------------------------------------------------------------- - const OStream& base() const noexcept { return os_; } - OStream& base() noexcept { return os_; } - - bool good() const { return os_.good(); } - - - //--------------------------------------------------------------- - /** @brief determines the leftmost border of the text body */ - formatting_ostream& first_column(int c) { - firstCol_ = c < 0 ? 0 : c; - return *this; - } - int first_column() const noexcept { return firstCol_; } - - /** @brief determines the rightmost border of the text body */ - formatting_ostream& last_column(int c) { - lastCol_ = c < 0 ? 0 : c; - return *this; - } - - int last_column() const noexcept { return lastCol_; } - - int text_width() const noexcept { - return lastCol_ - firstCol_; - } - - /** @brief additional indentation for the 2nd, 3rd, ... line of - a paragraph (sequence of soft-wrapped lines) */ - formatting_ostream& hanging_indent(int amount) { - hangingIndent_ = amount; - return *this; - } - int hanging_indent() const noexcept { - return hangingIndent_; - } - - /** @brief amount of blank lines between paragraphs */ - formatting_ostream& paragraph_spacing(int lines) { - paragraphSpacing_ = lines; - return *this; - } - int paragraph_spacing() const noexcept { - return paragraphSpacing_; - } - - /** @brief insert paragraph spacing - if paragraph is at least 'lines' lines long */ - formatting_ostream& min_paragraph_lines_for_spacing(int lines) { - paragraphSpacingThreshold_ = lines; - return *this; - } - int min_paragraph_lines_for_spacing() const noexcept { - return paragraphSpacingThreshold_; - } - - /** @brief if set to true, newline characters will be ignored */ - formatting_ostream& ignore_newline_chars(bool yes) { - ignoreInputNls_ = yes; - return *this; - } - - bool ignore_newline_chars() const noexcept { - return ignoreInputNls_; - } - - - //--------------------------------------------------------------- - /* @brief insert 'n' spaces */ - void write_spaces(int n) { - if(n < 1) return; - os_ << string_type(size_type(n), ' '); - curCol_ += n; - } - - /* @brief go to new line, but continue current paragraph */ - void wrap_soft(int times = 1) { - if(times < 1) return; - if(times > 1) { - os_ << string_type(size_type(times), '\n'); - } else { - os_ << '\n'; - } - curCol_ = 0; - ++curParagraphLines_; - } - - /* @brief go to new line, and start a new paragraph */ - void wrap_hard(int times = 1) { - if(times < 1) return; - - if(paragraph_spacing() > 0 && - paragraph_lines() >= min_paragraph_lines_for_spacing()) - { - times = paragraph_spacing() + 1; - } - - if(times > 1) { - os_ << string_type(size_type(times), '\n'); - curBlankLines_ += times - 1; - } else { - os_ << '\n'; - } - if(at_begin_of_line()) { - ++curBlankLines_; - } - curCol_ = 0; - curParagraphLines_ = 1; - } - - - //--------------------------------------------------------------- - bool at_begin_of_line() const noexcept { - return curCol_ <= current_line_begin(); - } - int current_line_begin() const noexcept { - return in_hanging_part_of_paragraph() - ? firstCol_ + hangingIndent_ - : firstCol_; - } - - int current_column() const noexcept { - return curCol_; - } - - int total_non_blank_lines() const noexcept { - return totalNonBlankLines_; - } - int paragraph_lines() const noexcept { - return curParagraphLines_; - } - int blank_lines_before_paragraph() const noexcept { - return curBlankLines_; - } - - - //--------------------------------------------------------------- - template - friend formatting_ostream& - operator << (formatting_ostream& os, const T& x) { - os.write(x); - return os; - } - - void flush() { - os_.flush(); - } - - -private: - bool in_hanging_part_of_paragraph() const noexcept { - return hanging_indent() > 0 && paragraph_lines() > 1; - } - bool current_line_empty() const noexcept { - return curCol_ < 1; - } - bool left_of_text_area() const noexcept { - return curCol_ < current_line_begin(); - } - bool right_of_text_area() const noexcept { - return curCol_ > lastCol_; - } - int columns_left_in_line() const noexcept { - return lastCol_ - std::max(current_line_begin(), curCol_); - } - - void fix_indent() { - if(left_of_text_area()) { - const auto fst = current_line_begin(); - write_spaces(fst - curCol_); - curCol_ = fst; - } - } - - template - bool only_whitespace(Iter first, Iter last) const { - return last == std::find_if_not(first, last, - [](char_type c) { return std::isspace(c); }); - } - - /** @brief write any object */ - template - void write(const T& x) { - std::ostringstream ss; - ss << x; - write(std::move(ss).str()); - } - - /** @brief write a stringstream */ - void write(const std::ostringstream& s) { - write(s.str()); - } - - /** @brief write a string */ - void write(const string_type& s) { - write(s.begin(), s.end()); - } - - /** @brief partition output into lines */ - template - void write(Iter first, Iter last) - { - if(first == last) return; - if(*first == '\n') { - if(!ignore_newline_chars()) wrap_hard(); - ++first; - if(first == last) return; - } - auto i = std::find(first, last, '\n'); - if(i != last) { - if(ignore_newline_chars()) ++i; - if(i != last) { - write_line(first, i); - write(i, last); - } - } - else { - write_line(first, last); - } - } - - /** @brief handle line wrapping due to column constraints */ - template - void write_line(Iter first, Iter last) - { - if(first == last) return; - if(only_whitespace(first, last)) return; - - if(right_of_text_area()) wrap_soft(); - - if(at_begin_of_line()) { - //discard whitespace, it we start a new line - first = std::find_if(first, last, - [](char_type c) { return !std::isspace(c); }); - if(first == last) return; - } - - const auto n = int(std::distance(first,last)); - const auto m = columns_left_in_line(); - //if text to be printed is too long for one line -> wrap - if(n > m) { - //break before word, if break is mid-word - auto breakat = first + m; - while(breakat > first && !std::isspace(*breakat)) --breakat; - //could not find whitespace before word -> try after the word - if(!std::isspace(*breakat) && breakat == first) { - breakat = std::find_if(first+m, last, - [](char_type c) { return std::isspace(c); }); - } - if(breakat > first) { - if(curCol_ < 1) ++totalNonBlankLines_; - fix_indent(); - std::copy(first, breakat, std::ostream_iterator(os_)); - curBlankLines_ = 0; - } - if(breakat < last) { - wrap_soft(); - write_line(breakat, last); - } - } - else { - if(curCol_ < 1) ++totalNonBlankLines_; - fix_indent(); - std::copy(first, last, std::ostream_iterator(os_)); - curCol_ += n; - curBlankLines_ = 0; - } - } - - /** @brief write a single character */ - void write(char_type c) - { - if(c == '\n') { - if(!ignore_newline_chars()) wrap_hard(); - } - else { - if(at_begin_of_line()) ++totalNonBlankLines_; - fix_indent(); - os_ << c; - ++curCol_; - } - } - - OStream& os_; - int curCol_; - int firstCol_; - int lastCol_; - int hangingIndent_; - int paragraphSpacing_; - int paragraphSpacingThreshold_; - int curBlankLines_; - int curParagraphLines_; - int totalNonBlankLines_; - bool ignoreInputNls_; -}; - - -} - - - - -/*************************************************************************//** - * - * @brief generates usage lines - * - * @details lazily evaluated - * - *****************************************************************************/ -class usage_lines -{ -public: - using string = doc_string; - - usage_lines(const group& cli, string prefix = "", - const doc_formatting& fmt = doc_formatting{}) - : - cli_(cli), fmt_(fmt), prefix_(std::move(prefix)) - { - if(!prefix_.empty()) prefix_ += ' '; - } - - usage_lines(const group& cli, const doc_formatting& fmt): - usage_lines(cli, "", fmt) - {} - - usage_lines& ommit_outermost_group_surrounders(bool yes) { - ommitOutermostSurrounders_ = yes; - return *this; - } - bool ommit_outermost_group_surrounders() const { - return ommitOutermostSurrounders_; - } - - template - inline friend OStream& operator << (OStream& os, const usage_lines& p) { - p.write(os); - return os; - } - - string str() const { - std::ostringstream os; os << *this; return os.str(); - } - - -private: - using stream_t = detail::formatting_ostream<>; - const group& cli_; - doc_formatting fmt_; - string prefix_; - bool ommitOutermostSurrounders_ = false; - - - //----------------------------------------------------- - struct context { - group::depth_first_traverser pos; - std::stack separators; - std::stack postfixes; - int level = 0; - const group* outermost = nullptr; - bool linestart = false; - bool useOutermost = true; - int line = 0; - - bool is_singleton() const noexcept { - return linestart && pos.is_last_in_path(); - } - bool is_alternative() const noexcept { - return pos.parent().exclusive(); - } - }; - - - /***************************************************************//** - * - * @brief writes usage text for command line parameters - * - *******************************************************************/ - template - void write(OStream& os) const - { - detail::formatting_ostream fos(os); - fos.first_column(fmt_.first_column()); - fos.last_column(fmt_.last_column()); - - auto hindent = int(prefix_.size()); - if(fos.first_column() + hindent >= int(0.4 * fos.text_width())) { - hindent = fmt_.indent_size(); - } - fos.hanging_indent(hindent); - - fos.paragraph_spacing(fmt_.paragraph_spacing()); - fos.min_paragraph_lines_for_spacing(2); - fos.ignore_newline_chars(fmt_.ignore_newline_chars()); - - context cur; - cur.pos = cli_.begin_dfs(); - cur.linestart = true; - cur.level = cur.pos.level(); - cur.outermost = &cli_; - - write(fos, cur, prefix_); - } - - - /***************************************************************//** - * - * @brief writes usage text for command line parameters - * - * @param prefix all that goes in front of current things to print - * - *******************************************************************/ - template - void write(OStream& os, context cur, string prefix) const - { - if(!cur.pos) return; - - std::ostringstream buf; - if(cur.linestart) buf << prefix; - const auto initPos = buf.tellp(); - - cur.level = cur.pos.level(); - - if(cur.useOutermost) { - //we cannot start outside of the outermost group - //so we have to treat it separately - start_group(buf, cur.pos.parent(), cur); - if(!cur.pos) { - os << buf.str(); - return; - } - } - else { - //don't visit siblings of starter node - cur.pos.skip_siblings(); - } - check_end_group(buf, cur); - - do { - if(buf.tellp() > initPos) cur.linestart = false; - if(!cur.linestart && !cur.pos.is_first_in_parent()) { - buf << cur.separators.top(); - } - if(cur.pos->is_group()) { - start_group(buf, cur.pos->as_group(), cur); - if(!cur.pos) { - os << buf.str(); - return; - } - } - else { - buf << param_label(cur.pos->as_param(), cur); - ++cur.pos; - } - check_end_group(buf, cur); - } while(cur.pos); - - os << buf.str(); - } - - - /***************************************************************//** - * - * @brief handles pattern group surrounders and separators - * and alternative splitting - * - *******************************************************************/ - void start_group(std::ostringstream& os, - const group& group, context& cur) const - { - //does cur.pos already point to a member or to group itself? - //needed for special treatment of outermost group - const bool alreadyInside = &(cur.pos.parent()) == &group; - - auto lbl = joined_label(group, cur); - if(!lbl.empty()) { - os << lbl; - cur.linestart = false; - //skip over entire group as its label has already been created - if(alreadyInside) { - cur.pos.next_after_siblings(); - } else { - cur.pos.next_sibling(); - } - } - else { - const bool splitAlternatives = group.exclusive() && - fmt_.split_alternatives() && - std::any_of(group.begin(), group.end(), - [this](const pattern& p) { - return int(p.param_count()) >= fmt_.alternatives_min_split_size(); - }); - - if(splitAlternatives) { - cur.postfixes.push(""); - cur.separators.push(""); - //recursively print alternative paths in decision-DAG - //enter group? - if(!alreadyInside) ++cur.pos; - cur.linestart = true; - cur.useOutermost = false; - auto pfx = os.str(); - os.str(""); - //print paths in DAG starting at each group member - for(std::size_t i = 0; i < group.size(); ++i) { - std::stringstream buf; - cur.outermost = cur.pos->is_group() ? &(cur.pos->as_group()) : nullptr; - write(buf, cur, pfx); - if(buf.tellp() > int(pfx.size())) { - os << buf.str(); - if(i < group.size()-1) { - if(cur.line > 0) { - os << string(fmt_.line_spacing(), '\n'); - } - ++cur.line; - os << '\n'; - } - } - cur.pos.next_sibling(); //do not descend into members - } - cur.pos.invalidate(); //signal end-of-path - return; - } - else { - //pre & postfixes, separators - auto surround = group_surrounders(group, cur); - os << surround.first; - cur.postfixes.push(std::move(surround.second)); - cur.separators.push(group_separator(group, fmt_)); - //descend into group? - if(!alreadyInside) ++cur.pos; - } - } - cur.level = cur.pos.level(); - } - - - /***************************************************************//** - * - *******************************************************************/ - void check_end_group(std::ostringstream& os, context& cur) const - { - for(; cur.level > cur.pos.level(); --cur.level) { - os << cur.postfixes.top(); - cur.postfixes.pop(); - cur.separators.pop(); - } - cur.level = cur.pos.level(); - } - - - /***************************************************************//** - * - * @brief makes usage label for one command line parameter - * - *******************************************************************/ - string param_label(const parameter& p, const context& cur) const - { - const auto& parent = cur.pos.parent(); - - const bool startsOptionalSequence = - parent.size() > 1 && p.blocking() && cur.pos.is_first_in_parent(); - - const bool outermost = - ommitOutermostSurrounders_ && cur.outermost == &parent; - - const bool showopt = !cur.is_alternative() && !p.required() - && !startsOptionalSequence && !outermost; - - const bool showrep = p.repeatable() && !outermost; - - string lbl; - - if(showrep) lbl += fmt_.repeat_prefix(); - if(showopt) lbl += fmt_.optional_prefix(); - - const auto& flags = p.flags(); - if(!flags.empty()) { - const int n = std::min(fmt_.max_flags_per_param_in_usage(), - int(flags.size())); - - const bool surrAlt = n > 1 && !showopt && !cur.is_singleton(); - - if(surrAlt) lbl += fmt_.alternative_flags_prefix(); - bool sep = false; - for(int i = 0; i < n; ++i) { - if(sep) { - if(cur.is_singleton()) - lbl += fmt_.alternative_group_separator(); - else - lbl += fmt_.flag_separator(); - } - lbl += flags[i]; - sep = true; - } - if(surrAlt) lbl += fmt_.alternative_flags_postfix(); - } - else { - if(!p.label().empty()) { - lbl += fmt_.label_prefix() - + p.label() - + fmt_.label_postfix(); - } else if(!fmt_.empty_label().empty()) { - lbl += fmt_.label_prefix() - + fmt_.empty_label() - + fmt_.label_postfix(); - } else { - return ""; - } - } - - if(showopt) lbl += fmt_.optional_postfix(); - if(showrep) lbl += fmt_.repeat_postfix(); - - return lbl; - } - - - /***************************************************************//** - * - * @brief prints flags in one group in a merged fashion - * - *******************************************************************/ - string joined_label(const group& g, const context& cur) const - { - if(!fmt_.merge_alternative_flags_with_common_prefix() && - !fmt_.merge_joinable_with_common_prefix()) return ""; - - const bool flagsonly = std::all_of(g.begin(), g.end(), - [](const pattern& p){ - return p.is_param() && !p.as_param().flags().empty(); - }); - - if(!flagsonly) return ""; - - const bool showOpt = g.all_optional() && - !(ommitOutermostSurrounders_ && cur.outermost == &g); - - auto pfx = g.common_flag_prefix(); - if(pfx.empty()) return ""; - - const auto n = pfx.size(); - if(g.exclusive() && - fmt_.merge_alternative_flags_with_common_prefix()) - { - string lbl; - if(showOpt) lbl += fmt_.optional_prefix(); - lbl += pfx + fmt_.alternatives_prefix(); - bool first = true; - for(const auto& p : g) { - if(p.is_param()) { - if(first) - first = false; - else - lbl += fmt_.alternative_param_separator(); - lbl += p.as_param().flags().front().substr(n); - } - } - lbl += fmt_.alternatives_postfix(); - if(showOpt) lbl += fmt_.optional_postfix(); - return lbl; - } - //no alternatives, but joinable flags - else if(g.joinable() && - fmt_.merge_joinable_with_common_prefix()) - { - const bool allSingleChar = std::all_of(g.begin(), g.end(), - [&](const pattern& p){ - return p.is_param() && - p.as_param().flags().front().substr(n).size() == 1; - }); - - if(allSingleChar) { - string lbl; - if(showOpt) lbl += fmt_.optional_prefix(); - lbl += pfx; - for(const auto& p : g) { - if(p.is_param()) - lbl += p.as_param().flags().front().substr(n); - } - if(showOpt) lbl += fmt_.optional_postfix(); - return lbl; - } - } - - return ""; - } - - - /***************************************************************//** - * - * @return symbols with which to surround a group - * - *******************************************************************/ - std::pair - group_surrounders(const group& group, const context& cur) const - { - string prefix; - string postfix; - - const bool isOutermost = &group == cur.outermost; - if(isOutermost && ommitOutermostSurrounders_) - return {string{}, string{}}; - - if(group.exclusive()) { - if(group.all_optional()) { - prefix = fmt_.optional_prefix(); - postfix = fmt_.optional_postfix(); - if(group.all_flagless()) { - prefix += fmt_.label_prefix(); - postfix = fmt_.label_prefix() + postfix; - } - } else if(group.all_flagless()) { - prefix = fmt_.label_prefix(); - postfix = fmt_.label_postfix(); - } else if(!cur.is_singleton() || !isOutermost) { - prefix = fmt_.alternatives_prefix(); - postfix = fmt_.alternatives_postfix(); - } - } - else if(group.size() > 1 && - group.front().blocking() && !group.front().required()) - { - prefix = fmt_.optional_prefix(); - postfix = fmt_.optional_postfix(); - } - else if(group.size() > 1 && cur.is_alternative() && - &group != cur.outermost) - { - prefix = fmt_.group_prefix(); - postfix = fmt_.group_postfix(); - } - else if(!group.exclusive() && - group.joinable() && !cur.linestart) - { - prefix = fmt_.joinable_prefix(); - postfix = fmt_.joinable_postfix(); - } - - if(group.repeatable()) { - if(prefix.empty()) prefix = fmt_.group_prefix(); - prefix = fmt_.repeat_prefix() + prefix; - if(postfix.empty()) postfix = fmt_.group_postfix(); - postfix += fmt_.repeat_postfix(); - } - - return {std::move(prefix), std::move(postfix)}; - } - - - /***************************************************************//** - * - * @return symbol that separates members of a group - * - *******************************************************************/ - static string - group_separator(const group& group, const doc_formatting& fmt) - { - const bool only1ParamPerMember = std::all_of(group.begin(), group.end(), - [](const pattern& p) { return p.param_count() < 2; }); - - if(only1ParamPerMember) { - if(group.exclusive()) { - return fmt.alternative_param_separator(); - } else { - return fmt.param_separator(); - } - } - else { //there is at least one large group inside - if(group.exclusive()) { - return fmt.alternative_group_separator(); - } else { - return fmt.group_separator(); - } - } - } -}; - - - - -/*************************************************************************//** - * - * @brief generates parameter and group documentation from docstrings - * - * @details lazily evaluated - * - *****************************************************************************/ -class documentation -{ -public: - using string = doc_string; - using filter_function = std::function; - - documentation(const group& cli, - const doc_formatting& fmt = doc_formatting{}, - filter_function filter = param_filter{}) - : - cli_(cli), fmt_{fmt}, usgFmt_{fmt}, filter_{std::move(filter)} - { - //necessary, because we re-use "usage_lines" to generate - //labels for documented groups - usgFmt_.max_flags_per_param_in_usage( - usgFmt_.max_flags_per_param_in_doc()); - } - - documentation(const group& cli, filter_function filter) : - documentation{cli, doc_formatting{}, std::move(filter)} - {} - - documentation(const group& cli, const param_filter& filter) : - documentation{cli, doc_formatting{}, - [filter](const parameter& p) { return filter(p); }} - {} - - template - inline friend OStream& operator << (OStream& os, const documentation& p) { - p.write(os); - return os; - } - - string str() const { - std::ostringstream os; - write(os); - return os.str(); - } - - -private: - using dfs_traverser = group::depth_first_traverser; - - const group& cli_; - doc_formatting fmt_; - doc_formatting usgFmt_; - filter_function filter_; - enum class paragraph { param, group }; - - - /***************************************************************//** - * - * @brief writes documentation to output stream - * - *******************************************************************/ - template - void write(OStream& os) const { - detail::formatting_ostream fos(os); - fos.first_column(fmt_.first_column()); - fos.last_column(fmt_.last_column()); - fos.hanging_indent(0); - fos.paragraph_spacing(0); - fos.ignore_newline_chars(fmt_.ignore_newline_chars()); - print_doc(fos, cli_); - } - - - /***************************************************************//** - * - * @brief writes full documentation text for command line parameters - * - *******************************************************************/ - template - void print_doc(detail::formatting_ostream& os, - const group& cli, int indentLvl = 0) const - { - if(cli.empty()) return; - - //if group itself doesn't have docstring - if(cli.doc().empty()) { - for(const auto& p : cli) { - print_doc(os, p, indentLvl); - } - } - else { //group itself does have docstring - bool anyDocInside = std::any_of(cli.begin(), cli.end(), - [](const pattern& p){ return !p.doc().empty(); }); - - if(anyDocInside) { //group docstring as title, then child entries - handle_spacing(os, paragraph::group, indentLvl); - os << cli.doc(); - for(const auto& p : cli) { - print_doc(os, p, indentLvl + 1); - } - } - else { //group label first then group docstring - auto lbl = usage_lines(cli, usgFmt_) - .ommit_outermost_group_surrounders(true).str(); - - str::trim(lbl); - handle_spacing(os, paragraph::param, indentLvl); - print_entry(os, lbl, cli.doc()); - } - } - } - - - /***************************************************************//** - * - * @brief writes documentation text for one group or parameter - * - *******************************************************************/ - template - void print_doc(detail::formatting_ostream& os, - const pattern& ptrn, int indentLvl) const - { - if(ptrn.is_group()) { - print_doc(os, ptrn.as_group(), indentLvl); - } - else { - const auto& p = ptrn.as_param(); - if(!filter_(p)) return; - - handle_spacing(os, paragraph::param, indentLvl); - print_entry(os, param_label(p, fmt_), p.doc()); - } - } - - /***************************************************************//** - * - * @brief handles line and paragraph spacings - * - *******************************************************************/ - template - void handle_spacing(detail::formatting_ostream& os, - paragraph p, int indentLvl) const - { - const auto oldIndent = os.first_column(); - const auto indent = fmt_.first_column() + indentLvl * fmt_.indent_size(); - - if(os.total_non_blank_lines() < 1) { - os.first_column(indent); - return; - } - - if(os.paragraph_lines() > 1 || indent < oldIndent) { - os.wrap_hard(fmt_.paragraph_spacing() + 1); - } else { - os.wrap_hard(); - } - - if(p == paragraph::group) { - if(os.blank_lines_before_paragraph() < fmt_.paragraph_spacing()) { - os.wrap_hard(fmt_.paragraph_spacing() - os.blank_lines_before_paragraph()); - } - } - else if(os.blank_lines_before_paragraph() < fmt_.line_spacing()) { - os.wrap_hard(fmt_.line_spacing() - os.blank_lines_before_paragraph()); - } - os.first_column(indent); - } - - /*********************************************************************//** - * - * @brief prints one entry = label + docstring - * - ************************************************************************/ - template - void print_entry(detail::formatting_ostream& os, - const string& label, const string& docstr) const - { - if(label.empty()) return; - - os << label; - - if(!docstr.empty()) { - if(os.current_column() >= fmt_.doc_column()) os.wrap_soft(); - const auto oldcol = os.first_column(); - os.first_column(fmt_.doc_column()); - os << docstr; - os.first_column(oldcol); - } - } - - - /*********************************************************************//** - * - * @brief makes label for one parameter - * - ************************************************************************/ - static doc_string - param_label(const parameter& param, const doc_formatting& fmt) - { - doc_string lbl; - - if(param.repeatable()) lbl += fmt.repeat_prefix(); - - const auto& flags = param.flags(); - if(!flags.empty()) { - lbl += flags[0]; - const int n = std::min(fmt.max_flags_per_param_in_doc(), - int(flags.size())); - for(int i = 1; i < n; ++i) { - lbl += fmt.flag_separator() + flags[i]; - } - } - else if(!param.label().empty() || !fmt.empty_label().empty()) { - lbl += fmt.label_prefix(); - if(!param.label().empty()) { - lbl += param.label(); - } else { - lbl += fmt.empty_label(); - } - lbl += fmt.label_postfix(); - } - - if(param.repeatable()) lbl += fmt.repeat_postfix(); - - return lbl; - } - -}; - - - - -/*************************************************************************//** - * - * @brief stores strings for man page sections - * - *****************************************************************************/ -class man_page -{ -public: - //--------------------------------------------------------------- - using string = doc_string; - - //--------------------------------------------------------------- - /** @brief man page section */ - class section { - public: - using string = doc_string; - - section(string stitle, string scontent): - title_{std::move(stitle)}, content_{std::move(scontent)} - {} - - const string& title() const noexcept { return title_; } - const string& content() const noexcept { return content_; } - - private: - string title_; - string content_; - }; - -private: - using section_store = std::vector
; - -public: - //--------------------------------------------------------------- - using value_type = section; - using const_iterator = section_store::const_iterator; - using size_type = section_store::size_type; - - - //--------------------------------------------------------------- - man_page& - append_section(string title, string content) - { - sections_.emplace_back(std::move(title), std::move(content)); - return *this; - } - //----------------------------------------------------- - man_page& - prepend_section(string title, string content) - { - sections_.emplace(sections_.begin(), - std::move(title), std::move(content)); - return *this; - } - - - //--------------------------------------------------------------- - const section& operator [] (size_type index) const noexcept { - return sections_[index]; - } - - //--------------------------------------------------------------- - size_type size() const noexcept { return sections_.size(); } - - bool empty() const noexcept { return sections_.empty(); } - - - //--------------------------------------------------------------- - const_iterator begin() const noexcept { return sections_.begin(); } - const_iterator end() const noexcept { return sections_.end(); } - - - //--------------------------------------------------------------- - man_page& program_name(const string& n) { - progName_ = n; - return *this; - } - man_page& program_name(string&& n) { - progName_ = std::move(n); - return *this; - } - const string& program_name() const noexcept { - return progName_; - } - - - //--------------------------------------------------------------- - man_page& section_row_spacing(int rows) { - sectionSpc_ = rows > 0 ? rows : 0; - return *this; - } - int section_row_spacing() const noexcept { return sectionSpc_; } - - -private: - int sectionSpc_ = 1; - section_store sections_; - string progName_; -}; - - - -/*************************************************************************//** - * - * @brief generates man sections from command line parameters - * with sections "synopsis" and "options" - * - *****************************************************************************/ -inline man_page -make_man_page(const group& cli, - doc_string progname = "", - const doc_formatting& fmt = doc_formatting{}) -{ - man_page man; - man.append_section("SYNOPSIS", usage_lines(cli,progname,fmt).str()); - man.append_section("OPTIONS", documentation(cli,fmt).str()); - return man; -} - - - -/*************************************************************************//** - * - * @brief generates man page based on command line parameters - * - *****************************************************************************/ -template -OStream& -operator << (OStream& os, const man_page& man) -{ - bool first = true; - const auto secSpc = doc_string(man.section_row_spacing() + 1, '\n'); - for(const auto& section : man) { - if(!section.content().empty()) { - if(first) first = false; else os << secSpc; - if(!section.title().empty()) os << section.title() << '\n'; - os << section.content(); - } - } - os << '\n'; - return os; -} - - - - - -/*************************************************************************//** - * - * @brief printing methods for debugging command line interfaces - * - *****************************************************************************/ -namespace debug { - - -/*************************************************************************//** - * - * @brief prints first flag or value label of a parameter - * - *****************************************************************************/ -inline doc_string doc_label(const parameter& p) -{ - if(!p.flags().empty()) return p.flags().front(); - if(!p.label().empty()) return p.label(); - return doc_string{""}; -} - -inline doc_string doc_label(const group&) -{ - return ""; -} - -inline doc_string doc_label(const pattern& p) -{ - return p.is_group() ? doc_label(p.as_group()) : doc_label(p.as_param()); -} - - -/*************************************************************************//** - * - * @brief prints parsing result - * - *****************************************************************************/ -template -void print(OStream& os, const parsing_result& result) -{ - for(const auto& m : result) { - os << "#" << m.index() << " " << m.arg() << " -> "; - auto p = m.param(); - if(p) { - os << doc_label(*p) << " \t"; - if(m.repeat() > 0) { - os << (m.bad_repeat() ? "[bad repeat " : "[repeat ") - << m.repeat() << "]"; - } - if(m.blocked()) os << " [blocked]"; - if(m.conflict()) os << " [conflict]"; - os << '\n'; - } - else { - os << " [unmapped]\n"; - } - } - - for(const auto& m : result.missing()) { - auto p = m.param(); - if(p) { - os << doc_label(*p) << " \t"; - os << " [missing after " << m.after_index() << "]\n"; - } - } -} - - -/*************************************************************************//** - * - * @brief prints parameter label and some properties - * - *****************************************************************************/ -template -void print(OStream& os, const parameter& p) -{ - if(p.greedy()) os << '!'; - if(p.blocking()) os << '~'; - if(!p.required()) os << '['; - os << doc_label(p); - if(p.repeatable()) os << "..."; - if(!p.required()) os << "]"; -} - - -//------------------------------------------------------------------- -template -void print(OStream& os, const group& g, int level = 0); - - -/*************************************************************************//** - * - * @brief prints group or parameter; uses indentation - * - *****************************************************************************/ -template -void print(OStream& os, const pattern& param, int level = 0) -{ - if(param.is_group()) { - print(os, param.as_group(), level); - } - else { - os << doc_string(4*level, ' '); - print(os, param.as_param()); - } -} - - -/*************************************************************************//** - * - * @brief prints group and its contents; uses indentation - * - *****************************************************************************/ -template -void print(OStream& os, const group& g, int level) -{ - auto indent = doc_string(4*level, ' '); - os << indent; - if(g.blocking()) os << '~'; - if(g.joinable()) os << 'J'; - os << (g.exclusive() ? "(|\n" : "(\n"); - for(const auto& p : g) { - print(os, p, level+1); - } - os << '\n' << indent << (g.exclusive() ? "|)" : ")"); - if(g.repeatable()) os << "..."; - os << '\n'; -} - - -} // namespace debug -} //namespace clipp - -#endif - diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_common.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_common.h deleted file mode 100644 index d85564d5e..000000000 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_common.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2024 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 通用数据结构 - -#ifndef STACK_ANALYZER_COMMON -#define STACK_ANALYZER_COMMON - -#include - -#define COMM_LEN 16 // 进程名最大长度 -#define MAX_STACKS 32 // 栈最大深度 -#define MAX_ENTRIES 102400 // map容量 - -/// @brief 栈计数的键,可以唯一标识一个用户内核栈 -typedef struct { - __u32 pid; - __s32 ksid, usid; -} psid; - -/// @brief 进程名 -typedef struct { - char str[COMM_LEN]; -} comm; - -#endif \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_ebpf.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_ebpf.h deleted file mode 100644 index 1dc55d83c..000000000 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_ebpf.h +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2024 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 用于eBPF程序的宏 - -#ifndef STACK_ANALYZER_EBPF -#define STACK_ANALYZER_EBPF - -#include "sa_common.h" - -#define PF_KTHREAD 0x00200000 -#define ignoreKthread(task) \ - do { \ - int flags = BPF_CORE_READ(task, flags); \ - if(flags & PF_KTHREAD) \ - return 0; \ - } while(false) - - -/// @brief 创建一个指定名字的ebpf调用栈表 -/// @param 新栈表的名字 -#define BPF_STACK_TRACE(name) \ - struct { \ - __uint(type, BPF_MAP_TYPE_STACK_TRACE); \ - __uint(key_size, sizeof(__u32)); \ - __uint(value_size, MAX_STACKS * sizeof(__u64)); \ - __uint(max_entries, MAX_ENTRIES); \ - } name SEC(".maps") - -/// @brief 创建一个指定名字和键值类型的ebpf散列表 -/// @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); \ - } name SEC(".maps") - -/// @brief 当前进程上下文内核态调用栈id -#define KERNEL_STACK bpf_get_stackid(ctx, &stack_trace, BPF_F_FAST_STACK_CMP) - -/// @brief 当前进程上下文用户态调用栈id -#define USER_STACK bpf_get_stackid(ctx, &stack_trace, BPF_F_FAST_STACK_CMP | BPF_F_USER_STACK) - -/** - * 用于在eBPF代码中声明通用的maps,其中 - * psid_count 存储 键值对,记录了id(由pid、ksid和usid(内核、用户栈id))及相应的值 - * stack_trace 存储 键值对,记录了栈id(ksid或usid)及相应的栈 - * pid_tgid 存储 键值对,记录pid以及对应的tgid - * pid_comm 存储 键值对,记录pid以及对应的命令名 - * type:指定count值的类型 - */ -#define DeclareCommonMaps(type) \ - BPF_HASH(psid_count, psid, type); \ - BPF_STACK_TRACE(stack_trace); \ - BPF_HASH(pid_tgid, u32, u32); \ - BPF_HASH(pid_comm, u32, comm); - -#define DeclareCommonVar() \ - bool u = false, k = false; \ - __u64 min = 0, max = 0; \ - int self_pid = 0; - -#endif \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_user.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_user.h deleted file mode 100644 index 16efa7119..000000000 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/sa_user.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2024 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 用户态使用的宏 - -#ifndef STACK_ANALYZER_USER -#define STACK_ANALYZER_USER - -#include -#include -#include -#include -#include -#include - -#include "sa_common.h" - -/// @brief 检查错误,若错误成立则打印带原因的错误信息并使上层函数返回-1 -/// @param cond 被检查的条件表达式 -/// @param info 要打印的错误信息 -#define CHECK_ERR(cond, ...) \ - if (cond) \ - { \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, " [%s]\n", strerror(errno)); \ - return -1; \ - } - -#include -/// @brief 检查错误,若错误成立则打印带原因的错误信息并退出 -/// @param cond 被检查的条件表达式 -/// @param info 要打印的错误信息 -#define CHECK_ERR_EXIT(cond, ...) \ - if (cond) \ - { \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, " [%s]\n", strerror(errno)); \ - exit(EXIT_FAILURE); \ - } - -#endif diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/task.h b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/task.h deleted file mode 100644 index 3fac9ec1d..000000000 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/task.h +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2019 Aqua Security Software Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// This product includes software developed by Aqua Security (https://aquasec.com). - -#ifndef __COMMON_TASK_H__ -#define __COMMON_TASK_H__ - -#include "vmlinux.h" - -#include - -#define statfunc static __always_inline - -struct pid_link { - struct hlist_node node; - struct pid *pid; -}; - -struct task_struct___older_v50 { - struct pid_link pids[PIDTYPE_MAX]; -}; - -statfunc u32 get_task_pid_vnr(struct task_struct *task) -{ - unsigned int level = 0; - struct pid *pid = NULL; - - if (bpf_core_type_exists(struct pid_link)) { - struct task_struct___older_v50 *t = (void *) task; - pid = BPF_CORE_READ(t, pids[PIDTYPE_PID].pid); - } else { - pid = BPF_CORE_READ(task, thread_pid); - } - - level = BPF_CORE_READ(pid, level); - - return BPF_CORE_READ(pid, numbers[level].nr); -} - -statfunc u32 get_task_ns_pid(struct task_struct *task) -{ - return get_task_pid_vnr(task); -} - -statfunc u32 get_task_ns_tgid(struct task_struct *task) -{ - struct task_struct *group_leader = BPF_CORE_READ(task, group_leader); - return get_task_pid_vnr(group_leader); -} - -statfunc u32 get_task_ns_ppid(struct task_struct *task) -{ - struct task_struct *real_parent = BPF_CORE_READ(task, real_parent); - return get_task_pid_vnr(real_parent); -} - -#endif \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src new file mode 120000 index 000000000..06c181236 --- /dev/null +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src @@ -0,0 +1 @@ +/home/a/Project/lmp/eBPF_Supermarket/Stack_Analyser/src/ \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/eBPFStackCollector.cpp b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/eBPFStackCollector.cpp deleted file mode 100644 index 18f1ff32f..000000000 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/eBPFStackCollector.cpp +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2024 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 包装用于采集调用栈数据的eBPF程序,规定一些抽象接口和通用变量 - -#include "bpf/eBPFStackCollector.h" -#include "sa_user.h" -#include "dt_symbol.h" - -#include -#include -#include -#include - -std::string getLocalDateTime(void) -{ - auto t = time(NULL); - auto localTm = localtime(&t); - char buff[32]; - strftime(buff, 32, "%Y%m%d_%H_%M_%S", localTm); - return std::string(buff); -}; - -bool operator<(const CountItem a, const CountItem b) -{ - if (a.v < b.v || (a.v == b.v && a.k.pid < b.k.pid)) - return true; - else - return false; -} - -StackCollector::StackCollector() -{ - self_pid = getpid(); -}; - -std::vector *StackCollector::sortedCountList(void) -{ - auto psid_count = bpf_object__find_map_by_name(obj, "psid_count"); - auto val_size = bpf_map__value_size(psid_count); - auto value_fd = bpf_object__find_map_fd_by_name(obj, "psid_count"); - - auto keys = new psid[MAX_ENTRIES]; - auto vals = new char[MAX_ENTRIES * val_size]; - uint32_t count = MAX_ENTRIES; - psid next_key; - int err; - if (showDelta) - { - err = bpf_map_lookup_and_delete_batch(value_fd, NULL, &next_key, keys, vals, &count, NULL); - } - else - { - err = bpf_map_lookup_batch(value_fd, NULL, &next_key, keys, vals, &count, NULL); - } - if (err == EFAULT) - { - return NULL; - } - - auto D = new std::vector(); - for (uint32_t i = 0; i < count; i++) - { - CountItem d(keys[i], count_value(vals + val_size * i)); - D->insert(std::lower_bound(D->begin(), D->end(), d), d); - } - delete[] keys; - delete[] vals; - return D; -}; - -StackCollector::operator std::string() -{ - std::ostringstream oss; - oss << "Type:" << scale.Type << " Unit:" << scale.Unit << " Period:" << scale.Period << '\n'; - oss << "time:" << getLocalDateTime() << '\n'; - std::map> traces; - - oss << "counts:\n"; - { - auto D = sortedCountList(); - if (!D) - return oss.str(); - oss << "pid\tusid\tksid\tcount\n"; - uint64_t trace[MAX_STACKS], *p; - for (auto i : *D) - { - auto &id = i.k; - auto &v = i.v; - auto trace_fd = bpf_object__find_map_fd_by_name(obj, "stack_trace"); - oss << id.pid << '\t' << id.usid << '\t' << id.ksid << '\t' << v << '\n'; - 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--) - ; - for (; p >= trace; p--) - { - 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)) - ; - 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 << (addr - sym.start); - sym.name += ss.str(); - g_symbol_parser.putin_symbol_cache(id.pid, addr, sym.name); - } - else - { - std::stringstream ss(""); - ss << "0x" << std::hex << addr; - sym.name = ss.str(); - g_symbol_parser.putin_symbol_cache(id.pid, addr, sym.name); - } - clearSpace(sym.name); - traces[id.usid].push_back(sym.name); - } - } - if (id.ksid > 0 && traces.find(id.ksid) == traces.end()) - { - bpf_map_lookup_elem(trace_fd, &id.ksid, trace); - for (p = trace + MAX_STACKS - 1; !*p; p--) - ; - for (; p >= trace; p--) - { - uint64_t &addr = *p; - symbol sym; - sym.reset(addr); - if (g_symbol_parser.find_kernel_symbol(sym)) - ; - else - { - std::stringstream ss(""); - ss << "0x" << std::hex << addr; - sym.name = ss.str(); - g_symbol_parser.putin_symbol_cache(pid, addr, sym.name); - } - clearSpace(sym.name); - traces[id.ksid].push_back(sym.name); - } - } - } - delete D; - } - - oss << "traces:\n"; - { - oss << "sid\ttrace\n"; - for (auto i : traces) - { - oss << i.first << "\t"; - for (auto s : i.second) - { - oss << s << ';'; - } - oss << "\n"; - } - } - - oss << "groups:\n"; - { - auto tgid_fd = bpf_object__find_map_fd_by_name(obj, "pid_tgid"); - if (tgid_fd < 0) - { - return oss.str(); - } - auto keys = new uint32_t[MAX_ENTRIES]; - auto vals = new uint32_t[MAX_ENTRIES]; - uint32_t count = MAX_ENTRIES; - uint32_t next_key; - int err = bpf_map_lookup_batch(tgid_fd, NULL, &next_key, keys, vals, - &count, NULL); - if (err == EFAULT) - { - return oss.str(); - } - oss << "pid\ttgid\n"; - for (uint32_t i = 0; i < count; i++) - { - oss << keys[i] << '\t' << vals[i] << '\n'; - } - delete[] keys; - delete[] vals; - } - - oss << "commands:\n"; - { - auto comm_fd = bpf_object__find_map_fd_by_name(obj, "pid_comm"); - if (comm_fd < 0) - { - return oss.str(); - } - auto keys = new uint32_t[MAX_ENTRIES]; - auto vals = new char[MAX_ENTRIES][16]; - uint32_t count = MAX_ENTRIES; - uint32_t next_key; - int err = bpf_map_lookup_batch(comm_fd, NULL, &next_key, keys, vals, - &count, NULL); - if (err == EFAULT) - { - return oss.str(); - } - oss << "pid\tcommand\n"; - for (uint32_t i = 0; i < count; i++) - { - oss << keys[i] << '\t' << vals[i] << '\n'; - } - delete[] keys; - delete[] vals; - } - - oss << "OK\n"; - return oss.str(); -} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/Makefile b/eBPF_Supermarket/Stack_Analyser/Makefile index 44a453a83..c7fd16d65 100644 --- a/eBPF_Supermarket/Stack_Analyser/Makefile +++ b/eBPF_Supermarket/Stack_Analyser/Makefile @@ -17,6 +17,7 @@ # Makefile OUTPUT := .output +BPF_SKEL := bpf_skel CLANG ?= clang LIBBPF_SRC := $(abspath libbpf-bootstrap/libbpf/src) BPFTOOL_SRC := $(abspath libbpf-bootstrap/bpftool/src) @@ -34,13 +35,13 @@ VMLINUX := libbpf-bootstrap/vmlinux/$(ARCH)/vmlinux.h # Use our own libbpf API headers and Linux UAPI headers distributed with # libbpf to avoid dependency on system-wide headers, which could be missing or # outdated -INCLUDES := -I./include -I$(OUTPUT) -I./libbpf-bootstrap/libbpf/include/uapi -I$(dir $(VMLINUX)) +INCLUDES := -I./include -I$(BPF_SKEL) -I./libbpf-bootstrap/libbpf/include/uapi -I$(dir $(VMLINUX)) CFLAGS := -g -Wall ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS) -BPF = $(patsubst src/bpf/%.bpf.c, %, ${wildcard src/bpf/*.bpf.c}) +BIN = $(patsubst src/%.cpp, %, ${wildcard src/*.cpp}) BPF_WAPPER = $(patsubst src/bpf/%.cpp, %, ${wildcard src/bpf/*.cpp}) -THIRD_PARTY = $(patsubst src/%.cc, %, ${wildcard src/*.cc}) +BPF = $(patsubst bpf/%.bpf.c, %, ${wildcard bpf/*.bpf.c}) TARGETS = stack_analyzer @@ -80,9 +81,6 @@ args = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}` .PHONY: all all: $(TARGETS) -.PHONY: bpf_skel_h -bpf_skel_h: $(BPF) - .PHONY: clean clean: $(call msg,CLEAN) @@ -92,12 +90,16 @@ $(OUTPUT) $(OUTPUT)/libbpf $(BPFTOOL_OUTPUT): $(call msg,MKDIR,$@) $(Q)mkdir -p $@ +$(BPF_SKEL): + $(call msg,MKDIR,$@) + $(Q)mkdir -p $@ + # Build libbpf $(LIBBPF_OBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(OUTPUT)/libbpf $(call msg,LIB,$@) - $(Q)$(MAKE) -C $(LIBBPF_SRC) BUILD_STATIC_ONLY=1 \ - OBJDIR=$(dir $@)/libbpf DESTDIR=$(dir $@) \ - INCLUDEDIR= LIBDIR= UAPIDIR= \ + $(Q)$(MAKE) -C $(LIBBPF_SRC) BUILD_STATIC_ONLY=1 \ + OBJDIR=$(dir $@)/libbpf DESTDIR=$(dir $@) \ + INCLUDEDIR= LIBDIR= UAPIDIR= \ install # Build bpftool @@ -106,7 +108,7 @@ $(BPFTOOL): | $(BPFTOOL_OUTPUT) $(Q)$(MAKE) ARCH= CROSS_COMPILE= OUTPUT=$(BPFTOOL_OUTPUT)/ -C $(BPFTOOL_SRC) bootstrap # Build BPF code -$(OUTPUT)/%.bpf.o: src/bpf/%.bpf.c $(LIBBPF_OBJ) $(wildcard %.h) $(VMLINUX) | $(OUTPUT) $(BPFTOOL) +$(OUTPUT)/%.bpf.o: bpf/%.bpf.c $(LIBBPF_OBJ) $(wildcard %.h) $(VMLINUX) | $(OUTPUT) $(BPFTOOL) $(call msg,BPF,$@) $(Q)$(CLANG) -g -O2 -target bpf -D__TARGET_ARCH_$(ARCH) \ $(INCLUDES) $(CLANG_BPF_SYS_INCLUDES) \ @@ -115,26 +117,22 @@ $(OUTPUT)/%.bpf.o: src/bpf/%.bpf.c $(LIBBPF_OBJ) $(wildcard %.h) $(VMLINUX) | $( # Generate BPF skeletons .PHONY: $(BPF) -$(BPF): %: $(OUTPUT)/%.bpf.o | $(OUTPUT) $(BPFTOOL) +$(BPF): %: $(OUTPUT)/%.bpf.o | $(OUTPUT) $(BPFTOOL) $(BPF_SKEL) $(call msg,GEN-SKEL,$@) - $(Q)$(BPFTOOL) gen skeleton $< > include/bpf/$@.skel.h + $(Q)$(BPFTOOL) gen skeleton $< > $(BPF_SKEL)/$@.skel.h -$(patsubst %,$(OUTPUT)/%.o,$(BPF_WAPPER)): $(OUTPUT)/%.o: src/bpf/%.cpp +$(patsubst %,$(OUTPUT)/%.o,$(BPF_WAPPER)): $(OUTPUT)/%.o: src/bpf/%.cpp $(BPF) $(call msg,CXX,$@) $(Q)$(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $@ # Build depending library -$(patsubst %,$(OUTPUT)/%.o,$(THIRD_PARTY)): $(OUTPUT)/%.o: src/%.cc +$(patsubst %,$(OUTPUT)/%.o,$(BIN)): $(OUTPUT)/%.o: src/%.cpp $(call msg,CXX,$@) $(Q)$(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $@ # $(Q)$(CXX) $(CFLAGS) $(INCLUDES) $< -E > log -$(OUTPUT)/$(TARGETS).o: main.cpp $(BPF) $(patsubst %,$(OUTPUT)/%.o,$(BPF_WAPPER)) | $(OUTPUT) - $(call msg,CXX,$@) - $(Q)$(CXX) $(CFLAGS) $(INCLUDES) -c main.cpp -o $@ - # Build application binary -$(TARGETS): %: $(OUTPUT)/%.o $(patsubst %,$(OUTPUT)/%.o,$(THIRD_PARTY)) $(patsubst %,$(OUTPUT)/%.o,$(BPF_WAPPER)) $(LIBBPF_OBJ) | $(OUTPUT) +$(TARGETS): $(patsubst %,$(OUTPUT)/%.o,$(BIN)) $(patsubst %,$(OUTPUT)/%.o,$(BPF_WAPPER)) $(LIBBPF_OBJ) | $(OUTPUT) $(call msg,BINARY,$@) $(Q)$(CXX) $^ $(ALL_LDFLAGS) -lstdc++ -lelf -lz -o $@ diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/io.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/io.bpf.c similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/io.bpf.c rename to eBPF_Supermarket/Stack_Analyser/bpf/io.bpf.c diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/mem.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/mem.bpf.c similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/mem.bpf.c rename to eBPF_Supermarket/Stack_Analyser/bpf/mem.bpf.c diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/off_cpu.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/off_cpu.bpf.c rename to eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/on_cpu.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/on_cpu.bpf.c similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/on_cpu.bpf.c rename to eBPF_Supermarket/Stack_Analyser/bpf/on_cpu.bpf.c diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/probe.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/probe.bpf.c similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/probe.bpf.c rename to eBPF_Supermarket/Stack_Analyser/bpf/probe.bpf.c diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/readahead.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/readahead.bpf.c similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/readahead.bpf.c rename to eBPF_Supermarket/Stack_Analyser/bpf/readahead.bpf.c diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/template.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/template.bpf.c similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf/template.bpf.c rename to eBPF_Supermarket/Stack_Analyser/bpf/template.bpf.c diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/IOStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/IOStackCollector.h deleted file mode 100644 index 5761cf425..000000000 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf/IOStackCollector.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _SA_IO_H__ -#define _SA_IO_H__ - -#include -typedef struct -{ - __u64 size : 40; - __u64 count : 24; -} io_tuple; - -#ifdef __cplusplus -#include "bpf/io_count.skel.h" -#include "bpf/eBPFStackCollector.h" - -class IOStackCollector : public StackCollector -{ -private: - declareEBPF(io_count_bpf); - -public: - enum io_mod - { - COUNT, - SIZE, - AVE, - } DataType = COUNT; - -protected: - virtual double count_value(void *); - -public: - void setScale(io_mod mod); - IOStackCollector(); - virtual int load(void); - virtual int attach(void); - virtual void detach(void); - virtual void unload(void); -}; -#endif - -#endif \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/MemoryStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/MemoryStackCollector.h deleted file mode 100644 index 70dcf9715..000000000 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf/MemoryStackCollector.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef _SA_MEMORY_H__ -#define _SA_MEMORY_H__ - -#include "bpf/eBPFStackCollector.h" -#include "bpf/mem_count.skel.h" -#include - -class MemoryStackCollector : public StackCollector -{ -private: - struct mem_count_bpf *skel = __null; - -public: - char *object = (char *)"libc.so.6"; - -protected: - virtual double count_value(void *d); - -public: - MemoryStackCollector(); - - virtual int load(void); - virtual int attach(void); - virtual void detach(void); - virtual void unload(void); - -/// @brief 向指定用户函数附加一个ebpf处理函数 -/// @param skel ebpf程序骨架 -/// @param sym_name 用户态函数名字面量,不加双引号 -/// @param prog_name ebpf处理函数,skel->progs中的成员名 -/// @param is_retprobe 布尔类型,是否附加到符号返回处 -#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0) -#define ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe) \ - do \ - { \ - DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts, \ - .retprobe = is_retprobe); \ - skel->links.prog_name = bpf_program__attach_uprobe_opts( \ - skel->progs.prog_name, \ - pid, \ - object, \ - 1, \ - &uprobe_opts); \ - } while (false) -#else -#define ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe) \ - do \ - { \ - LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts, \ - .retprobe = is_retprobe, \ - .func_name = #sym_name); \ - skel->links.prog_name = \ - bpf_program__attach_uprobe_opts( \ - skel->progs.prog_name, \ - pid, \ - object, \ - 0, \ - &uprobe_opts); \ - } while (false) -#endif - -/// @brief 向指定用户函数附加一个处理函数并检查是否连接成功 -/// @param skel ebpf程序骨架 -/// @param sym_name 要连接的用户函数 -/// @param prog_name ebpf处理函数 -/// @param is_retprobe 布尔类型,是否附加到函数返回处 -/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 -#define ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, is_retprobe) \ - do \ - { \ - ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe); \ - CHECK_ERR(!skel->links.prog_name, "no program attached for " #prog_name "\n") \ - } while (false) - -/// @brief 向指定用户态函数入口处附加一个处理函数并检查是否连接成功 -/// @param skel ebpf程序骨架 -/// @param sym_name 要跟踪的用户态函数名字面量,不带双引号 -/// @param prog_name ebpf处理函数,skel->progs中的成员 -/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 -#define at_ent(skel, sym_name, prog_name) ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, false) - -/// @brief 向指定用户态函数返回处附加一个处理函数并检查是否连接成功 -/// @param skel ebpf程序骨架 -/// @param sym_name 要附加的用户态函数名,字面量,不带双引号 -/// @param prog_name ebpf处理函数,skel->progs中的成员 -/// @note 如果检查到没有被附加则使上层函数返回负的错误代码 -#define at_ret(skel, sym_name, prog_name) ATTACH_UPROBE_CHECKED(skel, sym_name, prog_name, true) -}; - -#endif diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/OffCPUStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/OffCPUStackCollector.h deleted file mode 100644 index 6d3084870..000000000 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf/OffCPUStackCollector.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _SA_OFF_CPU_H__ -#define _SA_OFF_CPU_H__ - -#include "bpf/eBPFStackCollector.h" -#include "bpf/off_cpu_count.skel.h" - -class OffCPUStackCollector : public StackCollector -{ -private: - struct off_cpu_count_bpf *skel = __null; - -protected: - virtual double count_value(void*); - -public: - OffCPUStackCollector(); - virtual int load(void); - virtual int attach(void); - virtual void detach(void); - virtual void unload(void); -}; - -#endif \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/OnCPUStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/OnCPUStackCollector.h deleted file mode 100644 index 65f209a59..000000000 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf/OnCPUStackCollector.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _SA_ON_CPU_H__ -#define _SA_ON_CPU_H__ - -#include "eBPFStackCollector.h" -#include "on_cpu_count.skel.h" - - -#ifdef __cplusplus -class OnCPUStackCollector : public StackCollector -{ -private: - struct on_cpu_count_bpf *skel = __null; - - int *pefds = NULL; - int num_cpus = 0; - struct bpf_link **links = NULL; - unsigned long long freq = 49; - -protected: - virtual double count_value(void *); - -public: - void setScale(uint64_t freq); - OnCPUStackCollector(); - virtual int load(void); - virtual int attach(void); - virtual void detach(void); - virtual void unload(void); -}; -#endif - -#endif \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/ProbeStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/ProbeStackCollector.h deleted file mode 100644 index 90c80fbab..000000000 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf/ProbeStackCollector.h +++ /dev/null @@ -1,22 +0,0 @@ -#include "bpf/eBPFStackCollector.h" -#include "bpf/stack_count.skel.h" - -class StackCountStackCollector : public StackCollector -{ -private: - struct stack_count_bpf *skel = __null; - -public: - std::string probe; - -protected: - virtual double count_value(void *); - -public: - void setScale(std::string probe); - StackCountStackCollector(); - virtual int load(void); - virtual int attach(void); - virtual void detach(void); - virtual void unload(void); -}; diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/ReadaheadStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/ReadaheadStackCollector.h deleted file mode 100644 index 6df11f971..000000000 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf/ReadaheadStackCollector.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _SA_READAHEAD_H__ -#define _SA_READAHEAD_H__ - -#include -typedef struct -{ - __u32 expect; - __u32 truth; -} ra_tuple; - -#ifdef __cplusplus -#include "bpf/pre_count.skel.h" -#include "bpf/eBPFStackCollector.h" - -class ReadaheadStackCollector : public StackCollector -{ -private: - declareEBPF(pre_count_bpf); - -protected: - virtual double count_value(void *data); - -public: - ReadaheadStackCollector(); - virtual int load(void); - virtual int attach(void); - virtual void detach(void); - virtual void unload(void); -}; -#endif - -#endif \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/TemplateClass.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/TemplateClass.h deleted file mode 100644 index 9b464e9bb..000000000 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf/TemplateClass.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _TEMPLATE_H__ -#define _TEMPLATE_H__ - -// ========== C code part ========== - -// ========== C code end ========== - -#ifdef __cplusplus -// ========== C++ code part ========== -#include "bpf/template.skel.h" -#include "bpf/eBPFStackCollector.h" - -class TemplateClass : public StackCollector -{ -private: - declareEBPF(template_bpf); - -protected: - virtual double count_value(void *); - -public: - TemplateClass(); - virtual int load(void); - virtual int attach(void); - virtual void detach(void); - virtual void unload(void); -}; -// ========== C++ code end ========== -#endif - -#endif \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/eBPFStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/eBPFStackCollector.h index 70ccd56d0..137eb723a 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf/eBPFStackCollector.h +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf/eBPFStackCollector.h @@ -1,3 +1,21 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// 包装用于采集调用栈数据的eBPF程序,声明接口、通用成员和一些辅助结构 + #ifndef _SA_STACK_COLLECTOR_H__ #define _SA_STACK_COLLECTOR_H__ @@ -78,7 +96,7 @@ class StackCollector virtual void unload(void) = 0; // 声明eBPF骨架 -#define declareEBPF(eBPFName) struct eBPFName *skel = NULL; +#define declareEBPF(func) struct func##_bpf *skel = NULL; /// @brief 加载、初始化参数并打开指定类型的ebpf程序 /// @param ... 一些ebpf程序全局变量初始化语句 diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/io.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/io.h similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/io.h rename to eBPF_Supermarket/Stack_Analyser/include/bpf/io.h diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/mem.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/mem.h similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/mem.h rename to eBPF_Supermarket/Stack_Analyser/include/bpf/mem.h diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/off_cpu.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/off_cpu.h similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/off_cpu.h rename to eBPF_Supermarket/Stack_Analyser/include/bpf/off_cpu.h diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/on_cpu.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/on_cpu.h similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/on_cpu.h rename to eBPF_Supermarket/Stack_Analyser/include/bpf/on_cpu.h diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/probe.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/probe.h similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/probe.h rename to eBPF_Supermarket/Stack_Analyser/include/bpf/probe.h diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/readahead.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/readahead.h similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/readahead.h rename to eBPF_Supermarket/Stack_Analyser/include/bpf/readahead.h diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/template.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/template.h similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/bpf/template.h rename to eBPF_Supermarket/Stack_Analyser/include/bpf/template.h diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/dt_elf.h b/eBPF_Supermarket/Stack_Analyser/include/dt_elf.h similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/dt_elf.h rename to eBPF_Supermarket/Stack_Analyser/include/dt_elf.h diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/dt_symbol.h b/eBPF_Supermarket/Stack_Analyser/include/dt_symbol.h similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/include/dt_symbol.h rename to eBPF_Supermarket/Stack_Analyser/include/dt_symbol.h diff --git a/eBPF_Supermarket/Stack_Analyser/include/elf.hpp b/eBPF_Supermarket/Stack_Analyser/include/elf.hpp deleted file mode 100644 index 7e02c0ea9..000000000 --- a/eBPF_Supermarket/Stack_Analyser/include/elf.hpp +++ /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 "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/sa_common.h b/eBPF_Supermarket/Stack_Analyser/include/sa_common.h index 5735de509..d85564d5e 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/sa_common.h +++ b/eBPF_Supermarket/Stack_Analyser/include/sa_common.h @@ -1,4 +1,4 @@ -// Copyright 2023 The LMP Authors. +// Copyright 2024 The LMP Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h b/eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h index accbcba88..1dc55d83c 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h +++ b/eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h @@ -1,4 +1,4 @@ -// Copyright 2023 The LMP Authors. +// Copyright 2024 The LMP Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/eBPF_Supermarket/Stack_Analyser/include/sa_user.h b/eBPF_Supermarket/Stack_Analyser/include/sa_user.h index cee3b9c19..16efa7119 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/sa_user.h +++ b/eBPF_Supermarket/Stack_Analyser/include/sa_user.h @@ -1,4 +1,4 @@ -// Copyright 2023 The LMP Authors. +// Copyright 2024 The LMP Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/eBPF_Supermarket/Stack_Analyser/include/symbol.h b/eBPF_Supermarket/Stack_Analyser/include/symbol.h deleted file mode 100644 index 38237e0bb..000000000 --- a/eBPF_Supermarket/Stack_Analyser/include/symbol.h +++ /dev/null @@ -1,178 +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); - - /// @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/main.cpp b/eBPF_Supermarket/Stack_Analyser/main.cpp deleted file mode 100644 index e529c5459..000000000 --- a/eBPF_Supermarket/Stack_Analyser/main.cpp +++ /dev/null @@ -1,200 +0,0 @@ -#include -#include - -#include "bpf/OnCPUStackCollector.h" -#include "bpf/OffCPUStackCollector.h" -#include "bpf/MemoryStackCollector.h" -#include "bpf/IOStackCollector.h" -#include "bpf/ReadaheadStackCollector.h" -#include "bpf/ProbeStackCollector.h" - -#include "sa_user.h" -#include "clipp.h" - - -namespace MainConfig -{ - int run_time = __INT_MAX__; // 运行时间 - unsigned delay = 5; // 设置输出间隔 - std::string command = ""; - int32_t target_pid = -1; -} - -std::vector StackCollectorList; - -void endCollect(void) -{ - signal(SIGINT, SIG_IGN); - for (auto Item : StackCollectorList) - { - if (MainConfig::run_time > 0) - { - std::cout << std::string(*Item) << std::endl; - } - Item->detach(); - Item->unload(); - } - if (MainConfig::command.length()) - { - kill(MainConfig::target_pid, SIGTERM); - } -} - -uint64_t IntTmp; -std::string StrTmp; - -int main(int argc, char *argv[]) -{ - auto MainOption = (( - ((clipp::option("-p", "--pid") & clipp::value("pid of sampled process, default -1 for all", MainConfig::target_pid)) % "set pid of process to monitor") | - ((clipp::option("-c", "--command") & clipp::value("to be sampled command to run, default none", MainConfig::command)) % "set command for monitoring the whole life")), - (clipp::option("-d", "--delay") & clipp::value("delay time(seconds) to output, default 5", MainConfig::delay)) % "set the interval to output", - (clipp::option("-t", "--timeout") & clipp::value("run time, default nearly infinite", MainConfig::run_time)) % "set the total simpling time"); - - auto SubOption = (clipp::option("-U", "--user-stack-only").call([] - { StackCollectorList.back()->kstack = false; }) % - "only sample user stacks", - clipp::option("-K", "--kernel-stack-only").call([] - { StackCollectorList.back()->ustack = false; }) % - "only sample kernel stacks", - (clipp::option("-m", "--max-value") & clipp::value("max threshold of sampled value", IntTmp).call([] - { StackCollectorList.back()->max = IntTmp; })) % - "set the max threshold of sampled value", - (clipp::option("-n", "--min-value") & clipp::value("min threshold of sampled value", IntTmp).call([] - { StackCollectorList.back()->min = IntTmp; })) % - "set the min threshold of sampled value"); - - auto OnCpuOption = (clipp::option("on-cpu").call([] - { StackCollectorList.push_back(new OnCPUStackCollector()); }) % - "sample the call stacks of on-cpu processes") & - (clipp::option("-F", "--frequency") & clipp::value("sampling frequency", IntTmp).call([] - { static_cast(StackCollectorList.back())->setScale(IntTmp); }) % - "sampling at a set frequency", - SubOption); - - auto OffCpuOption = clipp::option("off-cpu").call([] - { StackCollectorList.push_back(new OffCPUStackCollector()); }) % - "sample the call stacks of off-cpu processes" & - SubOption; - - auto MemoryOption = clipp::option("mem").call([] - { StackCollectorList.push_back(new MemoryStackCollector()); }) % - "sample the memory usage of call stacks" & - SubOption; - - auto IOOption = clipp::option("io").call([] - { StackCollectorList.push_back(new IOStackCollector()); }) % - "sample the IO data volume of call stacks" & - ((clipp::option("--mod") & (clipp::option("count").call([] - { static_cast(StackCollectorList.back())->setScale(IOStackCollector::io_mod::COUNT); }) % - "Counting the number of I/O operations" | - clipp::option("ave").call([] - { static_cast(StackCollectorList.back())->setScale(IOStackCollector::io_mod::AVE); }) % - "Counting the ave of I/O operations" | - clipp::option("size").call([] - { static_cast(StackCollectorList.back())->setScale(IOStackCollector::io_mod::SIZE); }) % - "Counting the size of I/O operations")) % - "set the statistic mod", - SubOption); - - auto ReadaheadOption = clipp::option("ra").call([] - { StackCollectorList.push_back(new ReadaheadStackCollector()); }) % - "sample the readahead hit rate of call stacks" & - SubOption; - auto StackCountOption = clipp::option("stackcount").call([] - { StackCollectorList.push_back(new StackCountStackCollector()); }) % - "sample the counts of calling stacks" & - (clipp::option("-S", "--String") & clipp::value("probe String", StrTmp).call([] - { static_cast(StackCollectorList.back())->setScale(StrTmp); }) % - "sampling at a set probe string", - SubOption); - - auto cli = (MainOption, - clipp::option("-v", "--version").call([] - { std::cout << "verion 2.0\n\n"; }) % - "show version", - OnCpuOption, - OffCpuOption, - MemoryOption, - IOOption, - ReadaheadOption, - StackCountOption) % - "statistic call trace relate with some metrics"; - - if (!clipp::parse(argc, argv, cli)) - { - std::cout << clipp::make_man_page(cli, argv[0]) << '\n'; - return 0; - } - - uint64_t eventbuff = 1; - int child_exec_event_fd = eventfd(0, EFD_CLOEXEC); - CHECK_ERR(child_exec_event_fd < 0, "failed to create event fd"); - if (MainConfig::command.length()) - { - MainConfig::target_pid = fork(); - switch (MainConfig::target_pid) - { - case -1: - { - std::cout << "command create failed." << std::endl; - return -1; - } - case 0: - { - const auto bytes = read(child_exec_event_fd, &eventbuff, sizeof(eventbuff)); - CHECK_ERR(bytes < 0, "failed to read from fd %ld", bytes) - else CHECK_ERR(bytes != sizeof(eventbuff), "read unexpected size %ld", bytes); - printf("child exec %s\n", MainConfig::command.c_str()); - CHECK_ERR_EXIT(execl("/bin/bash", "bash", "-c", MainConfig::command.c_str(), NULL), "failed to execute child command"); - break; - } - default: - { - printf("create child %d\n", MainConfig::target_pid); - break; - } - } - } - - for (auto Item = StackCollectorList.begin(); Item != StackCollectorList.end();) - { - (*Item)->pid = MainConfig::target_pid; - if ((*Item)->load()) - { - goto err; - } - if ((*Item)->attach()) - { - goto err; - } - Item++; - continue; - err: - fprintf(stderr, "%s eBPF prog err\n", (*Item)->scale.Type); - (*Item)->detach(); - (*Item)->unload(); - Item = StackCollectorList.erase(Item); - } - - if (MainConfig::command.length()) - { - printf("wake up child\n"); - write(child_exec_event_fd, &eventbuff, sizeof(eventbuff)); - } - - // printf("display mode: %d\n", MainConfig::d_mode); - - for (; MainConfig::run_time > 0 && (MainConfig::target_pid < 0 || !kill(MainConfig::target_pid, 0)); MainConfig::run_time -= MainConfig::delay) - { - sleep(MainConfig::delay); - for (auto Item : StackCollectorList) - { - Item->detach(); - std::cout << std::string(*Item); - Item->attach(); - } - } - - atexit(endCollect); -} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/new_bpf.sh b/eBPF_Supermarket/Stack_Analyser/new_bpf.sh index c5266bcfd..afa503a12 100755 --- a/eBPF_Supermarket/Stack_Analyser/new_bpf.sh +++ b/eBPF_Supermarket/Stack_Analyser/new_bpf.sh @@ -13,18 +13,18 @@ done class_name=$name"StackCollector" -cp include/bpf/TemplateClass.h include/bpf/$class_name.h -sed -i 's/_TEMPLATE_H__/_SA_'$upper_name'_H__/g' include/bpf/$class_name.h -sed -i 's/TemplateClass/'$class_name'/g' include/bpf/$class_name.h -sed -i 's/template/'$origin_name'/g' include/bpf/$class_name.h +cp include/bpf/TemplateClass.h include/bpf/$origin_name.h +sed -i 's/_TEMPLATE_H__/_SA_'$upper_name'_H__/g' include/bpf/$origin_name.h +sed -i 's/TemplateClass/'$class_name'/g' include/bpf/$origin_name.h +sed -i 's/template/'$origin_name'/g' include/bpf/$origin_name.h -cp src/bpf/TemplateClass.cpp src/bpf/$class_name.cpp -sed -i 's/TemplateClass/'$class_name'/g' src/bpf/$class_name.cpp +cp src/bpf/TemplateClass.cpp src/bpf/$origin_name.cpp +sed -i 's/TemplateClass/'$class_name'/g' src/bpf/$origin_name.cpp cp src/bpf/template.bpf.c src/bpf/$origin_name.bpf.c sed -i 's/TemplateClass/'$class_name'/g' src/bpf/$origin_name.bpf.c -sed -i '/#include "bpf\/OnCPUStackCollector.h"/a#include "bpf\/'$class_name'.h"' main.cpp +sed -i '/#include "bpf\/on_cpu.h"/a#include "bpf\/'$origin_name'.h"' main.cpp sed -i '/auto cli = (MainOption,/iauto '$name'Option = (clipp::option("'$origin_name'").call([]{ StackCollectorList.push_back(new '$class_name'()); }) %"sample the '$origin_name' of calling stacks") & (SubOption);' main.cpp diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/IOStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/IOStackCollector.cpp deleted file mode 100644 index 5160adf42..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/IOStackCollector.cpp +++ /dev/null @@ -1,55 +0,0 @@ - -#include "bpf/IOStackCollector.h" - -double IOStackCollector::count_value(void *data) -{ - io_tuple *p = (io_tuple *)data; - switch (DataType) - { - case AVE: - return 1. * p->size / p->count; - case SIZE: - return p->size; - case COUNT: - return p->count; - default: - return 0; - } -}; - -void IOStackCollector::setScale(io_mod mod) -{ - DataType = mod; - static const char *Types[] = {"IOCount", "IOSize", "AverageIOSize"}; - static const char *Units[] = {"counts", "bytes", "bytes"}; - scale.Type = Types[mod]; - scale.Unit = Units[mod]; - scale.Period = 1; -}; - -IOStackCollector::IOStackCollector() -{ - setScale(DataType); -}; - -int IOStackCollector::load(void) -{ - StackProgLoadOpen(); - return 0; -} - -int IOStackCollector::attach(void) -{ - defaultAttach; - return 0; -} - -void IOStackCollector::detach(void) -{ - defaultDetach; -} - -void IOStackCollector::unload(void) -{ - defaultUnload; -} diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/MemoryStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/MemoryStackCollector.cpp deleted file mode 100644 index 93e204365..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/MemoryStackCollector.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "bpf/MemoryStackCollector.h" - -double MemoryStackCollector::count_value(void *d) -{ - return *(uint64_t *)d; -} - -MemoryStackCollector::MemoryStackCollector() -{ - kstack = false; - showDelta = false; - scale.Period = 1; - scale.Type = "LeakedMomery"; - scale.Unit = "bytes"; -}; - -int MemoryStackCollector::load(void) -{ - StackProgLoadOpen(); - return 0; -}; - -int MemoryStackCollector::attach(void) -{ - at_ent(skel, malloc, malloc_enter); - at_ret(skel, malloc, malloc_exit); - at_ent(skel, calloc, calloc_enter); - at_ret(skel, calloc, calloc_exit); - at_ent(skel, realloc, realloc_enter); - at_ret(skel, realloc, realloc_exit); - at_ent(skel, free, free_enter); - - at_ent(skel, mmap, mmap_enter); - at_ret(skel, mmap, mmap_exit); - at_ent(skel, munmap, munmap_enter); - - err = skel->attach(skel); - CHECK_ERR(err, "Failed to attach BPF skeleton"); - return 0; -}; - -void MemoryStackCollector::detach(void) -{ - skel->detach(skel); -#define des(name) \ - if (skel->links.name) \ - { \ - bpf_link__destroy(skel->links.name); \ - } - - des(malloc_enter); - des(malloc_exit); - des(calloc_enter); - des(calloc_exit); - des(realloc_enter); - des(realloc_exit); - des(free_enter); - des(mmap_enter); - des(mmap_exit); - des(munmap_enter); -}; - -void MemoryStackCollector::unload(void) -{ - defaultUnload; -} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/OffCPUStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/OffCPUStackCollector.cpp deleted file mode 100644 index b3c9864f9..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/OffCPUStackCollector.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "bpf/OffCPUStackCollector.h" - -OffCPUStackCollector::OffCPUStackCollector() -{ - scale.Period = 1 << 20; - scale.Type = "OffCPUTime"; - scale.Unit = "milliseconds"; -}; - -double OffCPUStackCollector::count_value(void *data) -{ - return *(uint32_t *)data; -}; - -int OffCPUStackCollector::load(void) -{ - StackProgLoadOpen(skel->bss->apid = pid;); - return 0; -} - -int OffCPUStackCollector::attach(void) -{ - defaultAttach; - return 0; -} - -void OffCPUStackCollector::detach(void) { - defaultDetach; -} - -void OffCPUStackCollector::unload(void) { - defaultUnload; -} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/OnCPUStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/OnCPUStackCollector.cpp deleted file mode 100644 index a883a7045..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/OnCPUStackCollector.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include "bpf/OnCPUStackCollector.h" -#include -#include - -/// @brief staring perf event -/// @param hw_event attribution of the perf event -/// @param pid the pid to track. 0 for the calling process. -1 for all processes. -/// @param cpu the cpu to track. -1 for all cpu -/// @param group_fd fd of event group leader -/// @param flags setting -/// @return fd of perf event -static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, - unsigned long flags) -{ - return syscall(SYS_perf_event_open, hw_event, pid, cpu, group_fd, flags); -} - -extern "C" -{ - extern int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz); -} - -OnCPUStackCollector::OnCPUStackCollector() -{ - setScale(freq); -}; - -void OnCPUStackCollector::setScale(uint64_t freq) -{ - this->freq = freq; - scale.Period = 1e9 / freq; - scale.Type = "OnCPUTime"; - scale.Unit = "nanoseconds"; -} - -double OnCPUStackCollector::count_value(void *data) -{ - return *(uint32_t *)data; -}; - -int OnCPUStackCollector::load(void) -{ - FILE *fp = popen("cat /proc/kallsyms | grep \" avenrun\"", "r"); - CHECK_ERR(!fp, "Failed to draw flame graph"); - unsigned long *load_a; - fscanf(fp, "%p", &load_a); - pclose(fp); - StackProgLoadOpen(skel->bss->load_a = load_a;); - - return 0; -}; - -int OnCPUStackCollector::attach(void) -{ - const char *online_cpus_file = "/sys/devices/system/cpu/online"; - bool *online_mask; - int num_online_cpus; - err = parse_cpu_mask_file(online_cpus_file, &online_mask, &num_online_cpus); - CHECK_ERR(err, "Fail to get online CPU numbers"); - - num_cpus = libbpf_num_possible_cpus(); - CHECK_ERR(num_cpus <= 0, "Fail to get the number of processors"); - - struct perf_event_attr attr = { - .type = PERF_TYPE_SOFTWARE, // hardware event can't be used - .size = sizeof(attr), - .config = PERF_COUNT_SW_CPU_CLOCK, - .sample_freq = freq, - .inherit = 1, - .freq = 1, // use freq instead of period - }; - pefds = (int *)malloc(num_cpus * sizeof(int)); - for (int i = 0; i < num_cpus; i++) - { - pefds[i] = -1; - } - links = (struct bpf_link **)calloc(num_cpus, sizeof(struct bpf_link *)); - for (int cpu = 0; cpu < num_cpus; cpu++) - { - /* skip offline/not present CPUs */ - if (cpu >= num_online_cpus || !online_mask[cpu]) - { - continue; - } - /* Set up performance monitoring on a CPU/Core */ - int pefd = perf_event_open(&attr, pid, cpu, -1, 0); - CHECK_ERR(pefd < 0, "Fail to set up performance monitor on a CPU/Core"); - pefds[cpu] = pefd; - /* Attach a BPF program on a CPU */ - links[cpu] = bpf_program__attach_perf_event(skel->progs.do_stack, pefd); // 与内核bpf程序联系 - CHECK_ERR(!links[cpu], "Fail to attach bpf program"); - } - return 0; -} - -void OnCPUStackCollector::detach(void) -{ - if (links) - { - for (int cpu = 0; cpu < num_cpus; cpu++) - { - bpf_link__destroy(links[cpu]); - } - free(links); - links = NULL; - } - if (pefds) - { - for (int i = 0; i < num_cpus; i++) - { - if (pefds[i] >= 0) - { - close(pefds[i]); - } - } - free(pefds); - pefds = NULL; - } -}; - -void OnCPUStackCollector::unload(void) -{ - defaultUnload; -}; diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/ProbeStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/ProbeStackCollector.cpp deleted file mode 100644 index 3c69c5af1..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/ProbeStackCollector.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "bpf/ProbeStackCollector.h" - -double StackCountStackCollector::count_value(void *data) { - return *(uint32_t*)data; -} - -StackCountStackCollector::StackCountStackCollector() -{ - scale = { - .Type = "StackCounts", - .Unit = "Counts", - .Period = 1, - }; -}; - -void StackCountStackCollector::setScale(std::string probe) -{ - this->probe = probe; - scale.Type = (probe + scale.Type).c_str(); -}; - -int StackCountStackCollector::load(void) -{ - StackProgLoadOpen(); - return 0; -}; - -int StackCountStackCollector::attach(void) -{ - skel->links.handle = - bpf_program__attach_kprobe(skel->progs.handle, false, probe.c_str()); - CHECK_ERR(!skel->links.handle, "Fail to attach kprobe"); - return 0; -}; - -void StackCountStackCollector::detach(void) -{ - defaultDetach; -}; - -void StackCountStackCollector::unload(void) -{ - defaultUnload; -}; diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/ReadaheadStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/ReadaheadStackCollector.cpp deleted file mode 100644 index e4b292658..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/ReadaheadStackCollector.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "bpf/ReadaheadStackCollector.h" - -double ReadaheadStackCollector::count_value(void *data) -{ - ra_tuple *p = (ra_tuple *)data; - return p->expect - p->truth; -}; - -ReadaheadStackCollector::ReadaheadStackCollector() -{ - showDelta = false; - scale = { - .Type = "UnusedReadaheadPages", - .Unit = "pages", - .Period = 1, - }; -}; - -int ReadaheadStackCollector::load(void) -{ - StackProgLoadOpen(); - return 0; -} - -int ReadaheadStackCollector::attach(void) -{ - defaultAttach; - return 0; -} - -void ReadaheadStackCollector::detach(void) -{ - defaultDetach; -} - -void ReadaheadStackCollector::unload(void) -{ - defaultUnload; -} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/TemplateClass.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/TemplateClass.cpp deleted file mode 100644 index 12a60eaf1..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/TemplateClass.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "bpf/TemplateClass.h" - -// ========== implement virtual func ========== - -double TemplateClass::count_value(void *data) -{ - return *(uint32_t*)data; -}; - -int TemplateClass::load(void) -{ - return 0; -}; - -int TemplateClass::attach(void) -{ - return 0; -}; - -void TemplateClass::detach(void){}; - -void TemplateClass::unload(void){}; - -// ========== other implementations ========== - -TemplateClass::TemplateClass(){}; \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/eBPFStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/eBPFStackCollector.cpp index b73c07f5a..18f1ff32f 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/eBPFStackCollector.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf/eBPFStackCollector.cpp @@ -1,6 +1,24 @@ +// Copyright 2024 The LMP Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// author: luiyanbing@foxmail.com +// +// 包装用于采集调用栈数据的eBPF程序,规定一些抽象接口和通用变量 + #include "bpf/eBPFStackCollector.h" #include "sa_user.h" -#include "symbol.h" +#include "dt_symbol.h" #include #include diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/io.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/io.cpp similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/io.cpp rename to eBPF_Supermarket/Stack_Analyser/src/bpf/io.cpp diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/io_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/src/bpf/io_count.bpf.c deleted file mode 100644 index fa6d1ccb4..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/io_count.bpf.c +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2023 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 内核态bpf的io-cpu模块代码 - -#include "vmlinux.h" -#include -#include -#include - -#include "sa_ebpf.h" -#include "bpf/IOStackCollector.h" -#include "task.h" - -DeclareCommonMaps(io_tuple); -DeclareCommonVar(); -int apid = 0; - -const char LICENSE[] SEC("license") = "GPL"; - -static int do_stack(struct trace_event_raw_sys_enter* ctx) -{ - struct task_struct* curr = (struct task_struct*)bpf_get_current_task(); //利用bpf_get_current_task()获得当前的进程tsk - ignoreKthread(curr); - u32 pid = get_task_ns_pid(curr); //利用帮助函数获得当前进程的pid - if ((apid >= 0 && pid != apid) || !pid || pid == self_pid) - return 0; - u64 len = BPF_CORE_READ(ctx, args[2]); // 读取系统调用的第三个参数 - if (len <= min || len > max) - return 0; - u32 tgid = get_task_ns_tgid(curr); //利用帮助函数获取进程的tgid - bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); //将pid_tgid表中的pid选项更新为tgid,若没有该表项,则创建 - comm* p = bpf_map_lookup_elem(&pid_comm, &pid); //p指向pid_comm哈希表中的pid表项对应的value - if (!p) //如果p不为空,获取当前进程名保存至name中,如果pid_comm当中不存在pid name项,则更新 - { - comm name; - bpf_get_current_comm(&name, COMM_LEN); - bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST); - } - psid apsid = { - .pid = pid, - .usid = u ? USER_STACK : -1, //u存在,则USER_STACK - .ksid = k ? KERNEL_STACK : -1, //K存在,则KERNEL_STACK - }; - - // record time delta - io_tuple* d = bpf_map_lookup_elem(&psid_count, &apsid); //count指向psid_count表当中的apsid表项,即size - - if (!d) { - io_tuple nd = { .count = 1, .size = len }; - bpf_map_update_elem(&psid_count, &apsid, &nd, BPF_NOEXIST); - } - else { - d->count++; - d->size += len; - } - return 0; -} - -#define io_sec_tp(name) \ - SEC("tp/syscalls/sys_enter_" #name) \ - int prog_t_##name(struct trace_event_raw_sys_enter *ctx) { return do_stack(ctx); } - -io_sec_tp(write); -io_sec_tp(read); -io_sec_tp(recvfrom); -io_sec_tp(sendto); - -// tracepoint:syscalls:sys_exit_select -// tracepoint:syscalls:sys_enter_poll -// tracepoint:syscalls:sys_enter_epoll_wait - - -// 1. 设置挂载点 -// tracepoint/syscalls/sys_enter_write 读操作 -// tracepoint/syscalls/sys_enter_read 写操作 -// tracepoint/syscalls/sys_enter_recvfrom 接收数据 -// tracepoint/syscalls/sys_enter_sendto 发送数据 - -//2. 执行程序 int prog_t_##name(struct trace_event_raw_sys_enter *ctx) { return do_stack(ctx); } -//最终调用上面的do_stack函数 \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/mem.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/mem.cpp similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/mem.cpp rename to eBPF_Supermarket/Stack_Analyser/src/bpf/mem.cpp diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/mem_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/src/bpf/mem_count.bpf.c deleted file mode 100644 index 40c96a743..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/mem_count.bpf.c +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright 2023 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 内核态ebpf的内存模块代码 - -#include "vmlinux.h" -#include -#include -#include - -#include "sa_ebpf.h" -#include "task.h" - -DeclareCommonMaps(u64); -DeclareCommonVar(); - -/// @brief 内存信息的键,唯一标识一块被分配的内存 -/// @note o为可初始化的填充对齐成员,贴合bpf verifier要求 -typedef struct -{ - __u64 addr; - __u32 pid, o; -} piddr; - -/// @brief 内存分配信息,可溯源的一次内存分配 -/// @note o为可初始化的填充对齐成员,贴合bpf verifier要求 -typedef struct -{ - __u64 size; - __u32 usid, o; -} mem_info; - -BPF_HASH(pid_size, u32, u64); // 记录了对应进程使用malloc,calloc等函数申请内存的大小 -BPF_HASH(piddr_meminfo, piddr, mem_info); // 记录了每次申请的内存空间的起始地址等信息 - -const char LICENSE[] SEC("license") = "GPL"; - -int gen_alloc_enter(size_t size) -{ - if (size <= min || size > max) - return 0; - struct task_struct *curr = (struct task_struct *)bpf_get_current_task(); - ignoreKthread(curr); - // update group - u32 pid = get_task_ns_pid(curr); - if (pid == self_pid) - return 0; - u32 tgid = get_task_ns_tgid(curr); - bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); - // update comm - if (!bpf_map_lookup_elem(&pid_comm, &pid)) - { - comm name; - bpf_get_current_comm(&name, COMM_LEN); - bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST); - } - // record size - return bpf_map_update_elem(&pid_size, &pid, &size, BPF_ANY); -} - -SEC("uprobe/malloc") -int BPF_KPROBE(malloc_enter, size_t size) -{ - return gen_alloc_enter(size); -} - -SEC("uprobe/calloc") -int BPF_KPROBE(calloc_enter, size_t nmemb, size_t size) -{ - return gen_alloc_enter(nmemb * size); -} - -SEC("uprobe/mmap") -int BPF_KPROBE(mmap_enter) -{ - size_t size = PT_REGS_PARM2(ctx); - return gen_alloc_enter(size); -} - -int gen_alloc_exit(struct pt_regs *ctx) -{ - void *addr = (void *)PT_REGS_RC(ctx); - if (!addr) - { - return 0; - } - u32 pid = get_task_ns_pid((struct task_struct *)bpf_get_current_task()); - u64 *size = bpf_map_lookup_elem(&pid_size, &pid); - if (!size) - { - return 0; - } - // record counts - psid apsid = { - .pid = pid, - .usid = u ? USER_STACK : -1, - .ksid = k ? KERNEL_STACK : -1, - }; - u64 *count = bpf_map_lookup_elem(&psid_count, &apsid); - if (!count) - { - bpf_map_update_elem(&psid_count, &apsid, size, BPF_NOEXIST); - } - else - { - __sync_fetch_and_add(count, *size); - } - // record pid_addr-info - piddr a = { - .addr = (u64)addr, - .pid = pid, - .o = 0, - }; - mem_info info = { - .size = *size, - .usid = apsid.usid, - .o = 0, - }; - return bpf_map_update_elem(&piddr_meminfo, &a, &info, BPF_NOEXIST); -} - -SEC("uretprobe/malloc") -int BPF_KRETPROBE(malloc_exit) -{ - return gen_alloc_exit(ctx); -} - -SEC("uretprobe/calloc") -int BPF_KRETPROBE(calloc_exit) -{ - return gen_alloc_exit(ctx); -} - -SEC("uretprobe/realloc") -int BPF_KRETPROBE(realloc_exit) -{ - return gen_alloc_exit(ctx); -} - -SEC("uretprobe/mmap") -int BPF_KRETPROBE(mmap_exit) -{ - return gen_alloc_exit(ctx); -} - -int gen_free_enter(u64 addr, size_t unsize) -{ - struct task_struct *curr = (struct task_struct *)bpf_get_current_task(); - u32 pid = get_task_ns_pid(curr); - piddr a = {.addr = addr, .pid = pid, .o = 0}; - mem_info *info = bpf_map_lookup_elem(&piddr_meminfo, &a); - if (!info) - return -1; - - // get allocated size - psid apsid = { - .ksid = -1, - .pid = pid, - .usid = info->usid, - }; - - u64 *size = bpf_map_lookup_elem(&psid_count, &apsid); - if (!size) - return -1; - - // sub the freeing size - if (unsize) - { - if (unsize >= *size) - { - *size = 0; - } - else - { - __sync_fetch_and_sub(size, unsize); - } - } - else - { - __sync_fetch_and_sub(size, info->size); - } - - if (*size == 0) - { - bpf_map_delete_elem(&psid_count, &apsid); - } - - // del freeing addr info - return bpf_map_delete_elem(&piddr_meminfo, &a); -} - -SEC("uprobe/free") -int BPF_KPROBE(free_enter, void *addr) -{ - return gen_free_enter((u64)addr, 0); -} - -SEC("uprobe/realloc") -int BPF_KPROBE(realloc_enter, void *ptr, size_t size) -{ - gen_free_enter((u64)ptr, 0); - return gen_alloc_enter(size); -} - -SEC("uprobe/munmap") -int BPF_KPROBE(munmap_enter, void *addr, size_t unsize) -{ - return gen_free_enter((u64)addr, unsize); -} diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/off_cpu.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/off_cpu.cpp similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/off_cpu.cpp rename to eBPF_Supermarket/Stack_Analyser/src/bpf/off_cpu.cpp diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/off_cpu_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/src/bpf/off_cpu_count.bpf.c deleted file mode 100644 index 7bdaf0527..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/off_cpu_count.bpf.c +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2023 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 内核态bpf的off-cpu模块代码 - -#include "vmlinux.h" -#include -#include -#include - -#include "sa_ebpf.h" -#include "task.h" - -DeclareCommonMaps(u32); -DeclareCommonVar(); - -int apid = 0; -BPF_HASH(start, u32, u64); //记录进程运行的起始时间 - -const char LICENSE[] SEC("license") = "GPL"; - -SEC("kprobe/finish_task_switch.isra.0") //动态挂载点finish_task_switch.isra.0 -int BPF_KPROBE(do_stack, struct task_struct *curr) -{ - // u32 pid = BPF_CORE_READ(curr, pid); - u32 pid = get_task_ns_pid(curr); //利用帮助函数获取当前进程tsk的pid - ignoreKthread(curr); - if ((apid >= 0 && pid == apid) || (apid < 0 && pid && pid != self_pid)) - { - // record curr block time - u64 ts = bpf_ktime_get_ns(); //ts=当前的时间戳(ns) - bpf_map_update_elem(&start, &pid, &ts, BPF_NOEXIST); //如果start表中不存在pid对应的时间,则就创建pid-->ts - } - - // calculate time delta, next ready to run - struct task_struct *next = (struct task_struct *)bpf_get_current_task();//next指向当前的结构体 - // pid = BPF_CORE_READ(next, pid); - pid = get_task_ns_pid(next); //利用帮助函数获取next指向的tsk的pid - u64 *tsp = bpf_map_lookup_elem(&start, &pid); //tsp指向start表中的pid的值 - if (!tsp) - return 0; - bpf_map_delete_elem(&start, &pid); //存在tsp,则删除pid对应的值 - u32 delta = (bpf_ktime_get_ns() - *tsp) >> 20; //delta为当前时间戳 - 原先tsp指向start表中的pid的值.代表运行时间 - - if ((delta <= min) || (delta > max)) - return 0; - - // record data - // u32 tgid = BPF_CORE_READ(next, tgid); - u32 tgid = get_task_ns_tgid(curr); //利用帮助函数获取当前进程的的tgid - bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); //利用帮助函数更新tgid对应的pid表项 - comm *p = bpf_map_lookup_elem(&pid_comm, &pid); //p指向pid_comm中pid对应的表项 - if (!p) - { - comm name; - bpf_probe_read_kernel_str(&name, COMM_LEN, next->comm); //获取next指向的进程结构体的comm,赋值给comm - bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST); //如果pid_comm中不存在pid项,则创建 - } - psid apsid = { - .pid = pid, - .usid = u ? USER_STACK : -1, - .ksid = k ? KERNEL_STACK : -1, - }; - - // record time delta - u32 *count = bpf_map_lookup_elem(&psid_count, &apsid); //count指向psid_count中的apsid对应的值 - if (count) - (*count) += delta; //如果count存在,则psid_count中的apsid对应的值+=时间戳 - else - bpf_map_update_elem(&psid_count, &apsid, &delta, BPF_NOEXIST); //如果不存在,则将psid_count表中的apsid设置为delta - return 0; -} \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/on_cpu.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/on_cpu.cpp similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/on_cpu.cpp rename to eBPF_Supermarket/Stack_Analyser/src/bpf/on_cpu.cpp diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/on_cpu_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/src/bpf/on_cpu_count.bpf.c deleted file mode 100644 index 1b479dcf9..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/on_cpu_count.bpf.c +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2023 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 内核态bpf的on-cpu模块代码 - -#include "vmlinux.h" -#include -#include -#include - -#include "sa_ebpf.h" -#include "task.h" - -const char LICENSE[] SEC("license") = "GPL"; - -DeclareCommonMaps(u32); -DeclareCommonVar(); -unsigned long *load_a = NULL; - -SEC("perf_event") //挂载点为perf_event -int do_stack(void *ctx) -{ - unsigned long load; - bpf_core_read(&load, sizeof(unsigned long), load_a); //load为文件中读出的地址,则该地址开始读取unsigned long大小字节的数据保存到load - load >>= 11; //load右移11 - bpf_printk("%lu %lu", load, min); //输出load 以及min - if (load < min || load > max) - return 0; - // record data - struct task_struct *curr = (void *)bpf_get_current_task(); //curr指向当前进程的tsk - ignoreKthread(curr); // 忽略内核线程 - u32 pid = get_task_ns_pid(curr); //pid保存当前进程的pid,是cgroup pid 对应的level 0 pid - if (!pid || pid == self_pid) - return 0; - u32 tgid = get_task_ns_tgid(curr); //tgid保存当前进程的tgid - bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); //更新pid_tgid表中的pid表项 - comm *p = bpf_map_lookup_elem(&pid_comm, &pid); //p指向pid_comm中的Pid对应的值 - if (!p) - { - comm name; - bpf_probe_read_kernel_str(&name, COMM_LEN, curr->comm); //name中保存的是当前进程tsk的进程名 - bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST); //更新pid_comm中的进程号对应的进程名 - } - psid apsid = { - .pid = pid, - .usid = u ? USER_STACK : -1, - .ksid = k ? KERNEL_STACK : -1, - }; - - // add cosunt - u32 *count = bpf_map_lookup_elem(&psid_count, &apsid); //count指向psid_count对应的apsid的值 - if (count) - (*count)++; //count不为空,则psid_count对应的apsid的值+1 - else - { - u32 orig = 1; - bpf_map_update_elem(&psid_count, &apsid, &orig, BPF_ANY); //否则psid_count对应的apsid的值=1 - } - return 0; -} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/pre_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/src/bpf/pre_count.bpf.c deleted file mode 100644 index 6d5e95581..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/pre_count.bpf.c +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2023 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: luiyanbing@foxmail.com -// -// 内核态bpf的预读取分析模块代码 - -#include "vmlinux.h" -#include -#include -#include - -#include "sa_ebpf.h" -#include "task.h" -#include "bpf/ReadaheadStackCollector.h" - -#define MINBLOCK_US 1ULL -#define MAXBLOCK_US 99999999ULL - -DeclareCommonMaps(ra_tuple); -DeclareCommonVar(); - -int apid = 0; -BPF_HASH(in_ra, u32, psid); -BPF_HASH(page_psid, struct page *, psid); - -SEC("fentry/page_cache_ra_unbounded") // fentry在内核函数page_cache_ra_unbounded进入时触发的挂载点 -int BPF_PROG(page_cache_ra_unbounded) -{ - struct task_struct *curr = (struct task_struct *)bpf_get_current_task(); - ignoreKthread(curr); - u32 pid = get_task_ns_pid(curr); // 获取当前进程tgid,用户空间的pid即是tgid - - if ((apid >= 0 && pid != apid) || !pid || pid == self_pid) - return 0; - - u32 tgid = get_task_ns_tgid(curr); - bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); // 更新pid_tgid表中的pid对应的值 - comm *p = bpf_map_lookup_elem(&pid_comm, &pid); // p指向pid_comm表中pid对应的值 - if (!p) - { - comm name; - bpf_get_current_comm(&name, COMM_LEN); // 获取当前进程名 - bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST); // 在pid_comm表中更新pid对应的值 - } - - psid apsid = { - .pid = pid, - .usid = u ? USER_STACK : -1, - .ksid = k ? KERNEL_STACK : -1, - }; - - ra_tuple *d = bpf_map_lookup_elem(&psid_count, &apsid); // d指向psid_count表中的apsid对应的类型为tuple的值 - if (!d) - { - ra_tuple a = {.expect = 0, .truth = 0}; // 初始化为0 - bpf_map_update_elem(&psid_count, &apsid, &a, BPF_ANY); // 更新psid_count表中的apsid的值为a - } - bpf_map_update_elem(&in_ra, &pid, &apsid, BPF_ANY); // 更新in_ra表中的pid对应的值为apsid - return 0; -} - -SEC("fexit/alloc_pages") // fexit在内核函数alloc_pages退出时触发,挂载点为alloc_pages -int BPF_PROG(filemap_alloc_folio_ret, gfp_t gfp, unsigned int order, u64 ret) -{ - u32 pid = bpf_get_current_pid_tgid() >> 32; // pid为当前进程的pid - - if ((apid >= 0 && pid != apid) || !pid) - return 0; - - struct psid *apsid = bpf_map_lookup_elem(&in_ra, &pid); // apsid指向了当前in_ra中pid的表项内容 - if (!apsid) - return 0; - - ra_tuple *a = bpf_map_lookup_elem(&psid_count, apsid); // a是指向psid_count的apsid对应的内容 - if (!a) - return 0; - - const u32 lim = 1ul << order; // 1 为长整型,左移order位,即2^order 即申请页的大小 - a->expect += lim; // a->expect+=页大小(未访问) - u64 addr; - bpf_core_read(&addr, sizeof(u64), &ret); // alloc_pages返回的值,即申请页的起始地址保存在addr中 - for (int i = 0; i < lim && i < 1024; i++, addr += 0x1000) - bpf_map_update_elem(&page_psid, &addr, apsid, BPF_ANY); // 更新page_psid表中的addr(从页的起始地址开始到页的结束地址)所对应的值为apsid - - return 0; -} - -SEC("fexit/page_cache_ra_unbounded") -int BPF_PROG(page_cache_ra_unbounded_ret) // fexit在内核函数page_cache_ra_unbounded退出时触发的挂载点 -{ - u32 pid = bpf_get_current_pid_tgid() >> 32; // 获取当前进程的pid - - if ((apid >= 0 && pid != apid) || !pid) - return 0; - - bpf_map_delete_elem(&in_ra, &pid); // 删除了in_ra对应的pid的表项,即删除对应的栈计数信息 - return 0; -} - -SEC("fentry/mark_page_accessed") // fentry在内核函数/mark_page_accessed进入时触发的挂载点,用于标记页面(page)已经被访问 -int BPF_PROG(mark_page_accessed, u64 page) -{ - u32 pid = bpf_get_current_pid_tgid() >> 32; // 获取当前进程的pid - - if ((apid >= 0 && pid != apid) || !pid) - return 0; - psid *apsid; - apsid = bpf_map_lookup_elem(&page_psid, &page); // 查看page_psid对应的 地址page 对应类型为psid的值,并保存在apsid - if (!apsid) - return 0; - ra_tuple *a = bpf_map_lookup_elem(&psid_count, apsid); // a指向psid_count的apsid的内容 - if (!a) - return 0; - a->truth++; // 已访问 - bpf_map_delete_elem(&page_psid, &page); // 删除page_psid的page对应的内容 - return 0; -} - -const char LICENSE[] SEC("license") = "GPL"; \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/probe.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/probe.cpp similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/probe.cpp rename to eBPF_Supermarket/Stack_Analyser/src/bpf/probe.cpp diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/readahead.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/readahead.cpp similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/readahead.cpp rename to eBPF_Supermarket/Stack_Analyser/src/bpf/readahead.cpp diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/stack_count.bpf.c b/eBPF_Supermarket/Stack_Analyser/src/bpf/stack_count.bpf.c deleted file mode 100644 index 17afce185..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/stack_count.bpf.c +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2023 The LMP Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// author: GaoYixiang -// -// 内核态eBPF的通用的调用栈计数代码 - -#include "vmlinux.h" -#include -#include -#include - -#include "../include/sa_ebpf.h" -#include "../include/task.h" - -DeclareCommonMaps(u32); -DeclareCommonVar(); - -// 传进来的参数 -int apid = 0; - -const char LICENSE[] SEC("license") = "GPL"; - -static int handle_func(void *ctx) -{ - struct task_struct *curr = (struct task_struct *)bpf_get_current_task(); // 利用bpf_get_current_task()获得当前的进程tsk - ignoreKthread(curr); - - u32 pid = get_task_ns_pid(curr); // 利用帮助函数获得当前进程的pid - if ((apid >= 0 && pid != apid) || !pid || pid == self_pid) - return 0; - - u32 tgid = get_task_ns_tgid(curr); // 利用帮助函数获取进程的tgid - bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); // 将pid_tgid表中的pid选项更新为tgid,若没有该表项,则创建 - - if (!bpf_map_lookup_elem(&pid_comm, &pid)) - { - comm name; - bpf_get_current_comm(&name, COMM_LEN); - bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST); - } - - psid apsid = { - .pid = pid, - .usid = u ? USER_STACK : -1, - .ksid = k ? KERNEL_STACK : -1, - }; - - u32 *cnt = bpf_map_lookup_elem(&psid_count, &apsid); - if (!cnt) - { - u32 ONE = 1; - bpf_map_update_elem(&psid_count, &apsid, &ONE, BPF_NOEXIST); - } - else - { - (*cnt)++; - } - - return 0; -} - -SEC("kprobe/dummy_kprobe") -int BPF_KPROBE(handle) -{ - handle_func(ctx); - return 0; -} -SEC("tp/sched/dummy_tp") -int handle_tp(void *ctx) -{ - handle_func(ctx); - return 0; -} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/template.bpf.c b/eBPF_Supermarket/Stack_Analyser/src/bpf/template.bpf.c deleted file mode 100644 index 6e6b93a9d..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/template.bpf.c +++ /dev/null @@ -1,14 +0,0 @@ - -#include "vmlinux.h" -#include -#include -#include - -#include "sa_ebpf.h" -#include "bpf/TemplateClass.h" -#include "task.h" - -DeclareCommonMaps(__u32); -DeclareCommonVar(); - -const char LICENSE[] SEC("license") = "GPL"; \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/template.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/template.cpp similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/bpf/template.cpp rename to eBPF_Supermarket/Stack_Analyser/src/bpf/template.cpp diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/dt_elf.cpp b/eBPF_Supermarket/Stack_Analyser/src/dt_elf.cpp similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/dt_elf.cpp rename to eBPF_Supermarket/Stack_Analyser/src/dt_elf.cpp diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/dt_symbol.cpp b/eBPF_Supermarket/Stack_Analyser/src/dt_symbol.cpp similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/dt_symbol.cpp rename to eBPF_Supermarket/Stack_Analyser/src/dt_symbol.cpp diff --git a/eBPF_Supermarket/Stack_Analyser/src/elf.cc b/eBPF_Supermarket/Stack_Analyser/src/elf.cc deleted file mode 100644 index f58e76566..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/elf.cc +++ /dev/null @@ -1,625 +0,0 @@ -/* - * Linux内核诊断工具--elf相关公共函数 - * - * Copyright (C) 2020 Alibaba Ltd. - * - * License terms: GNU General Public License (GPL) version 3 - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -<<<<<<<< HEAD:eBPF_Supermarket/Stack_Analyser/src/elf.cc -#include "elf.hpp" -======== -#include "stack_analyzer/include/elf.h" ->>>>>>>> 642a5109ef5dd10a13d3e9a905aefffb9dfdb467:MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/elf.cc - -#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/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/main.cpp b/eBPF_Supermarket/Stack_Analyser/src/main.cpp similarity index 100% rename from MagicEyes/src/backend/system_diagnosis/stack_analyzer/src/main.cpp rename to eBPF_Supermarket/Stack_Analyser/src/main.cpp diff --git a/eBPF_Supermarket/Stack_Analyser/src/symbol.cc b/eBPF_Supermarket/Stack_Analyser/src/symbol.cc deleted file mode 100644 index 72b353dc8..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/symbol.cc +++ /dev/null @@ -1,563 +0,0 @@ -/* - * Linux内核诊断工具--用户态符号表解析 - * - * Copyright (C) 2020 Alibaba Ltd. - * - * License terms: GNU General Public License (GPL) version 3 - * - */ - -#include -#include -#include -#include - -#include "symbol.h" -#include "elf.hpp" - -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[256]; - 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::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; -} - -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 = 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 From 10bb16e8645f27ed3c17a957f7821c39a65d80c1 Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Sat, 16 Mar 2024 12:58:16 +0000 Subject: [PATCH 14/55] fix action err Signed-off-by: LiuLingze --- MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf | 2 +- MagicEyes/src/backend/system_diagnosis/stack_analyzer/include | 2 +- MagicEyes/src/backend/system_diagnosis/stack_analyzer/src | 2 +- eBPF_Supermarket/Stack_Analyser/Makefile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf index 1d246dce4..93c3bcab6 120000 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/bpf @@ -1 +1 @@ -/home/a/Project/lmp/eBPF_Supermarket/Stack_Analyser/bpf/ \ No newline at end of file +../../../../../eBPF_Supermarket/Stack_Analyser/bpf/ \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include index bd48a5e4f..a84d125b4 120000 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/include @@ -1 +1 @@ -/home/a/Project/lmp/eBPF_Supermarket/Stack_Analyser/include/ \ No newline at end of file +../../../../../eBPF_Supermarket/Stack_Analyser/include/ \ No newline at end of file diff --git a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src index 06c181236..4bb05db0e 120000 --- a/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src +++ b/MagicEyes/src/backend/system_diagnosis/stack_analyzer/src @@ -1 +1 @@ -/home/a/Project/lmp/eBPF_Supermarket/Stack_Analyser/src/ \ No newline at end of file +../../../../../eBPF_Supermarket/Stack_Analyser/src/ \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/Makefile b/eBPF_Supermarket/Stack_Analyser/Makefile index c7fd16d65..d4981ce74 100644 --- a/eBPF_Supermarket/Stack_Analyser/Makefile +++ b/eBPF_Supermarket/Stack_Analyser/Makefile @@ -35,7 +35,7 @@ VMLINUX := libbpf-bootstrap/vmlinux/$(ARCH)/vmlinux.h # Use our own libbpf API headers and Linux UAPI headers distributed with # libbpf to avoid dependency on system-wide headers, which could be missing or # outdated -INCLUDES := -I./include -I$(BPF_SKEL) -I./libbpf-bootstrap/libbpf/include/uapi -I$(dir $(VMLINUX)) +INCLUDES := -I./include -I$(OUTPUT) -I$(BPF_SKEL) -I./libbpf-bootstrap/libbpf/include/uapi -I$(dir $(VMLINUX)) CFLAGS := -g -Wall ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS) From 5dcb58a4abd410e1b868a9e08753d01cdf09abfa Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Sat, 16 Mar 2024 13:58:50 +0000 Subject: [PATCH 15/55] fix off cpu probe mismatching Signed-off-by: LiuLingze --- .../Stack_Analyser/include/dt_symbol.h | 1 + .../Stack_Analyser/src/bpf/off_cpu.cpp | 9 ++++++++- .../Stack_Analyser/src/dt_symbol.cpp | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/eBPF_Supermarket/Stack_Analyser/include/dt_symbol.h b/eBPF_Supermarket/Stack_Analyser/include/dt_symbol.h index 38237e0bb..3f2c3ffe9 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/dt_symbol.h +++ b/eBPF_Supermarket/Stack_Analyser/include/dt_symbol.h @@ -136,6 +136,7 @@ class symbol_parser { 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 符号对象 diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf/off_cpu.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf/off_cpu.cpp index f3bb2f7a6..7e392d9a1 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf/off_cpu.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf/off_cpu.cpp @@ -17,6 +17,7 @@ // off cpu ebpf程序的包装类,实现接口和一些自定义方法 #include "bpf/off_cpu.h" +#include "dt_symbol.h" OffCPUStackCollector::OffCPUStackCollector() { @@ -38,7 +39,13 @@ int OffCPUStackCollector::load(void) int OffCPUStackCollector::attach(void) { - defaultAttach; + symbol sym; + sym.name = "finish_task_switch"; + if(!g_symbol_parser.complete_kernel_symbol(sym)) + { + return -1; + } + skel->links.do_stack = bpf_program__attach_kprobe(skel->progs.do_stack, false, sym.name.c_str()); return 0; } diff --git a/eBPF_Supermarket/Stack_Analyser/src/dt_symbol.cpp b/eBPF_Supermarket/Stack_Analyser/src/dt_symbol.cpp index 921fff048..92feb0d7b 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/dt_symbol.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/dt_symbol.cpp @@ -274,6 +274,25 @@ bool symbol_parser::find_kernel_symbol(symbol &sym) 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 = From 22bba1e83b5ebb29f91dfe86f19fe06a6825fd10 Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Mon, 18 Mar 2024 08:06:35 +0000 Subject: [PATCH 16/55] fix bpf code Signed-off-by: LiuLingze --- eBPF_Supermarket/Stack_Analyser/bpf/mem.bpf.c | 10 +++++----- eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c | 2 +- eBPF_Supermarket/Stack_Analyser/include/bpf/mem.h | 15 --------------- 3 files changed, 6 insertions(+), 21 deletions(-) diff --git a/eBPF_Supermarket/Stack_Analyser/bpf/mem.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/mem.bpf.c index 868f97e07..e99a888e5 100644 --- a/eBPF_Supermarket/Stack_Analyser/bpf/mem.bpf.c +++ b/eBPF_Supermarket/Stack_Analyser/bpf/mem.bpf.c @@ -48,7 +48,7 @@ BPF_HASH(piddr_meminfo, piddr, mem_info); // 记录了每次申请的内存空 const char LICENSE[] SEC("license") = "GPL"; -int gen_alloc_enter(size_t size) +static int gen_alloc_enter(size_t size) { if (size <= min || size > max) return 0; @@ -90,9 +90,9 @@ int BPF_KPROBE(mmap_enter) return gen_alloc_enter(size); } -int gen_alloc_exit(struct pt_regs *ctx) +static int gen_alloc_exit(struct pt_regs *ctx) { - void *addr = (void *)PT_REGS_RC(ctx); + u64 addr = PT_REGS_RC(ctx); if (!addr) { return 0; @@ -120,7 +120,7 @@ int gen_alloc_exit(struct pt_regs *ctx) } // record pid_addr-info piddr a = { - .addr = (u64)addr, + .addr = addr, .pid = pid, .o = 0, }; @@ -156,7 +156,7 @@ int BPF_KRETPROBE(mmap_exit) return gen_alloc_exit(ctx); } -int gen_free_enter(u64 addr, size_t unsize) +static int gen_free_enter(u64 addr, size_t unsize) { struct task_struct *curr = (struct task_struct *)bpf_get_current_task(); u32 pid = get_task_ns_pid(curr); diff --git a/eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c index 356d8f898..e04d5fe46 100644 --- a/eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c +++ b/eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c @@ -32,7 +32,7 @@ BPF_HASH(start, u32, u64); // const char LICENSE[] SEC("license") = "GPL"; -SEC("kprobe/finish_task_switch.isra.0") //动态挂载点finish_task_switch.isra.0 +SEC("kprobe/finish_task_switch") //动态挂载点finish_task_switch.isra.0 int BPF_KPROBE(do_stack, struct task_struct *curr) { // u32 pid = BPF_CORE_READ(curr, pid); diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf/mem.h b/eBPF_Supermarket/Stack_Analyser/include/bpf/mem.h index 862f44122..7294dd663 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf/mem.h +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf/mem.h @@ -47,20 +47,6 @@ class MemoryStackCollector : public StackCollector /// @param sym_name 用户态函数名字面量,不加双引号 /// @param prog_name ebpf处理函数,skel->progs中的成员名 /// @param is_retprobe 布尔类型,是否附加到符号返回处 -#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0) -#define ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe) \ - do \ - { \ - DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts, \ - .retprobe = is_retprobe); \ - skel->links.prog_name = bpf_program__attach_uprobe_opts( \ - skel->progs.prog_name, \ - pid, \ - object, \ - 1, \ - &uprobe_opts); \ - } while (false) -#else #define ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe) \ do \ { \ @@ -75,7 +61,6 @@ class MemoryStackCollector : public StackCollector 0, \ &uprobe_opts); \ } while (false) -#endif /// @brief 向指定用户函数附加一个处理函数并检查是否连接成功 /// @param skel ebpf程序骨架 From 7639b856d83aa2134a072dc9526179b25ed87ff2 Mon Sep 17 00:00:00 2001 From: syxl-time <953879556@qq.com> Date: Mon, 18 Mar 2024 17:07:15 +0800 Subject: [PATCH 17/55] =?UTF-8?q?mem=5Fwatcher:=E6=B7=BB=E5=8A=A0=E5=86=85?= =?UTF-8?q?=E5=AD=98=E6=B3=84=E9=9C=B2=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Memory_Subsystem__mem_watcher.yml | 6 +- .../applications/mem_watcher/Makefile | 4 +- .../applications/mem_watcher/mem_watcher.c | 278 ++++++++++++++++-- .../applications/mem_watcher/mem_watcher.h | 17 ++ .../applications/mem_watcher/memleak.bpf.c | 115 ++++++++ .../applications/mem_watcher/memleak.c | 15 + 6 files changed, 399 insertions(+), 36 deletions(-) create mode 100644 eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/memleak.bpf.c create mode 100644 eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/memleak.c diff --git a/.github/workflows/Memory_Subsystem__mem_watcher.yml b/.github/workflows/Memory_Subsystem__mem_watcher.yml index e728d841b..3154eed0b 100644 --- a/.github/workflows/Memory_Subsystem__mem_watcher.yml +++ b/.github/workflows/Memory_Subsystem__mem_watcher.yml @@ -31,9 +31,5 @@ jobs: run: | cd eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/ bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h - make paf - make pr - make procstat - make sysstat - make mem_watcher + make sudo timeout 20 ./mem_watcher diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/Makefile b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/Makefile index b0d796afc..47d0ad558 100644 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/Makefile +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/Makefile @@ -24,13 +24,13 @@ INCLUDES := -I$(OUTPUT) -I../../libbpf/include/uapi -I$(dir $(VMLINUX)) -I$(LIBB CFLAGS := -g -Wall ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS) -APPS = paf pr procstat sysstat mem_watcher +APPS = paf pr procstat sysstat memleak CARGO ?= $(shell which cargo) ifeq ($(strip $(CARGO)),) BZS_APPS := else -BZS_APPS := +BZS_APPS := mem_watcher APPS += $(BZS_APPS) # Required by libblazesym ALL_LDFLAGS += -lrt -ldl -lpthread -lm diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.c b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.c index f241cd97a..3a0f1a6fe 100644 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.c +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.c @@ -16,7 +16,9 @@ // // mem_watcher libbpf user mode code +#include #include +#include #include #include #include @@ -28,14 +30,25 @@ #include "pr.skel.h" #include "procstat.skel.h" #include "sysstat.skel.h" +#include "memleak.skel.h" #include "mem_watcher.h" +#include "blazesym.h" + +static const int perf_max_stack_depth = 127; //stack id 对应的堆栈的深度 +static const int stack_map_max_entries = 10240; //最大允许存储多少个stack_id +static __u64 *g_stacks = NULL; +static size_t g_stacks_size = 0; + +static struct blaze_symbolizer *symbolizer; + static struct env { int time; bool paf; bool pr; bool procstat; bool sysstat; + bool memleak; bool part2; @@ -47,6 +60,7 @@ static struct env { .pr = false, .procstat = false, .sysstat = false, + .memleak = false, .rss = false, .part2 = false, }; @@ -69,7 +83,9 @@ static const struct argp_option opts[] = { {0, 0, 0, 0, "sysstat additional function:"}, {"part2", 'n', NULL, 0, "系统内存状态报告2", 7}, - {"time", 't', "TIME-SEC", 0, "Max Running Time(0 for infinite)", 8}, + {"memleak", 'l', "PID", 0, "print memleak (内存泄漏检测)", 8}, + + {"time", 't', "TIME-SEC", 0, "Max Running Time(0 for infinite)", 9}, {NULL, 'h', NULL, OPTION_HIDDEN, "show the full help"}, {0}, }; @@ -105,6 +121,9 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) { case 'R': env.rss = true; break; + case 'l': + env.memleak = true; + break; default: return ARGP_ERR_UNKNOWN; } @@ -117,6 +136,122 @@ static const struct argp argp = { .doc = argp_program_doc, }; +static void print_frame(const char *name, uintptr_t input_addr, uintptr_t addr, uint64_t offset, const blaze_symbolize_code_info* code_info) +{ + // If we have an input address we have a new symbol. + if (input_addr != 0) { + printf("%016lx: %s @ 0x%lx+0x%lx", input_addr, name, addr, offset); + if (code_info != NULL && code_info->dir != NULL && code_info->file != NULL) { + printf(" %s/%s:%u\n", code_info->dir, code_info->file, code_info->line); + } else if (code_info != NULL && code_info->file != NULL) { + printf(" %s:%u\n", code_info->file, code_info->line); + } else { + printf("\n"); + } + } else { + printf("%16s %s", "", name); + if (code_info != NULL && code_info->dir != NULL && code_info->file != NULL) { + printf("@ %s/%s:%u [inlined]\n", code_info->dir, code_info->file, code_info->line); + } else if (code_info != NULL && code_info->file != NULL) { + printf("@ %s:%u [inlined]\n", code_info->file, code_info->line); + } else { + printf("[inlined]\n"); + } + } +} + +static void show_stack_trace(__u64 *stack, int stack_sz, pid_t pid) { + const struct blaze_symbolize_inlined_fn *inlined; + const struct blaze_result *result; + const struct blaze_sym *sym; + int i, j; + + assert(sizeof(uintptr_t) == sizeof(uint64_t)); + + if (pid) { + struct blaze_symbolize_src_process src = { + .pid = pid, + }; + result = blaze_symbolize_process(symbolizer, &src, (const uintptr_t *)stack, stack_sz); + } + else { + struct blaze_symbolize_src_kernel src = {}; + result = blaze_symbolize_kernel(symbolizer, &src, (const uintptr_t *)stack, stack_sz); + } + + + for (i = 0; i < stack_sz; i++) { + if (!result || result->cnt <= i || result->syms[i].name == NULL) { + printf(" %2d [<%016llx>]\n", i, stack[i]); + continue; + } + + sym = &result->syms[i]; + print_frame(sym->name, stack[i], sym->addr, sym->offset, &sym->code_info); + + for (j = 0; j < sym->inlined_cnt; j++) { + inlined = &sym->inlined[j]; + print_frame(sym->name, 0, 0, 0, &inlined->code_info); + } + } + + blaze_result_free(result); +} + +int print_outstanding_combined_allocs(struct memleak_bpf *skel, pid_t pid) { + const size_t combined_allocs_key_size = bpf_map__key_size(skel->maps.combined_allocs); + const size_t stack_traces_key_size = bpf_map__key_size(skel->maps.stack_traces); + + for (__u64 prev_key = 0, curr_key = 0; ; prev_key = curr_key) { + + if (bpf_map__get_next_key(skel->maps.combined_allocs, + &prev_key, &curr_key, combined_allocs_key_size)) { + if (errno == ENOENT) { + break; //no more keys, done! + } + perror("map get next key failed!"); + + return -errno; + } + + // stack_id = curr_key + union combined_alloc_info cinfo; + memset(&cinfo, 0, sizeof(cinfo)); + + if (bpf_map__lookup_elem(skel->maps.combined_allocs, + &curr_key, combined_allocs_key_size, &cinfo, sizeof(cinfo), 0)) { + if (errno == ENOENT) { + continue; + } + + perror("map lookup failed!"); + return -errno; + } + + if (bpf_map__lookup_elem(skel->maps.stack_traces, + &curr_key, stack_traces_key_size, g_stacks, g_stacks_size, 0)) { + perror("failed to lookup stack traces!"); + return -errno; + } + + printf("stack_id=0x%llx with outstanding allocations: total_size=%llu nr_allocs=%llu\n", + curr_key, (__u64)cinfo.total_size, (__u64)cinfo.number_of_allocs); + + int stack_sz = 0; + for (int i = 0; i < perf_max_stack_depth; i++) { + if (g_stacks[i] == 0) { + break; + } + stack_sz++; + //printf("[%3d] 0x%llx\n", i, g_stacks[i]); + } + + show_stack_trace(g_stacks, stack_sz, pid); + } + + return 0; +} + static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) { return vfprintf(stderr, format, args); } @@ -125,6 +260,7 @@ static volatile bool exiting = false; static void sig_handler(int sig) { exiting = true; + exit(EXIT_SUCCESS); } /* @@ -242,13 +378,19 @@ int main(int argc, char **argv) { struct pr_bpf *skel_pr; struct procstat_bpf *skel_procstat; struct sysstat_bpf *skel_sysstat; + struct memleak_bpf *skel; + + int err, i; + LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts); + int attach_pid; + char binary_path[128] = { 0 }; - int err; err = argp_parse(&argp, argc, argv, 0, NULL, NULL); if (err) return err; own_pid = getpid(); libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + /* Set up libbpf errors and debug info callback */ libbpf_set_print(libbpf_print_fn); @@ -410,33 +552,106 @@ int main(int argc, char **argv) { } } - while (!exiting) { - if (env.paf) { - err = ring_buffer__poll(rb, 1000 /* timeout, ms */); - /* Ctrl-C will cause -EINTR */ - if (err == -EINTR) { - err = 0; - break; - } - if (err < 0) { - printf("Error polling perf buffer: %d\n", err); - break; - } + else if (env.memleak) { + if (argc != 3) { + printf("usage:%s attach_pid\n", argv[0]); + return -1; } - else if (env.pr) { - err = ring_buffer__poll(rb, 100 /* timeout, ms */); - /* Ctrl-C will cause -EINTR */ - if (err == -EINTR) { - err = 0; - break; - } - if (err < 0) { - printf("Error polling perf buffer: %d\n", err); - break; - } + + attach_pid = atoi(argv[2]); + + strcpy(binary_path, "/lib/x86_64-linux-gnu/libc.so.6"); + + /* Set up libbpf errors and debug info callback */ + libbpf_set_print(libbpf_print_fn); + + /* Load and verify BPF application */ + skel = memleak_bpf__open(); + if (!skel) { + fprintf(stderr, "Failed to open BPF skeleton\n"); + return 1; } - else if (env.procstat) { - err = ring_buffer__poll(rb, 100 /* timeout, ms */); + + bpf_map__set_value_size(skel->maps.stack_traces, perf_max_stack_depth * sizeof(__u64)); + bpf_map__set_max_entries(skel->maps.stack_traces, stack_map_max_entries); + + /* Load & verify BPF programs */ + err = memleak_bpf__load(skel); + if (err) { + fprintf(stderr, "Failed to load BPF skeleton\n"); + goto memleak_cleanup; + } + + /* Attach tracepoint handler */ + uprobe_opts.func_name = "malloc"; + uprobe_opts.retprobe = false; + /* uprobe/uretprobe expects relative offset of the function to attach + * to. libbpf will automatically find the offset for us if we provide the + * function name. If the function name is not specified, libbpf will try + * to use the function offset instead. + */ + skel->links.malloc_enter = bpf_program__attach_uprobe_opts(skel->progs.malloc_enter, + attach_pid /* self pid */, binary_path, + 0 /* offset for function */, + &uprobe_opts /* opts */); + if (!skel->links.malloc_enter) { + err = -errno; + fprintf(stderr, "Failed to attach uprobe: %d\n", err); + goto memleak_cleanup; + } + + uprobe_opts.func_name = "malloc"; + uprobe_opts.retprobe = true; + skel->links.malloc_exit = bpf_program__attach_uprobe_opts(skel->progs.malloc_exit, + attach_pid, binary_path, + 0, &uprobe_opts); + if (!skel->links.malloc_exit) { + err = -errno; + fprintf(stderr, "Failed to attach uprobe: %d\n", err); + goto memleak_cleanup; + } + + uprobe_opts.func_name = "free"; + uprobe_opts.retprobe = false; + skel->links.free_enter = bpf_program__attach_uprobe_opts(skel->progs.free_enter, + attach_pid, binary_path, + 0, &uprobe_opts); + if (!skel->links.free_enter) { + err = -errno; + fprintf(stderr, "Failed to attach uprobe: %d\n", err); + goto memleak_cleanup; + } + + /* Let libbpf perform auto-attach for uprobe_sub/uretprobe_sub + * NOTICE: we provide path and symbol info in SEC for BPF programs + */ + err = memleak_bpf__attach(skel); + if (err) { + fprintf(stderr, "Failed to auto-attach BPF skeleton: %d\n", err); + goto memleak_cleanup; + } + + g_stacks_size = perf_max_stack_depth * sizeof(*g_stacks); + g_stacks = (__u64 *)malloc(g_stacks_size); + memset(g_stacks, 0, g_stacks_size); + + symbolizer = blaze_symbolizer_new(); + if (!symbolizer) { + fprintf(stderr, "Fail to create a symbolizer\n"); + err = -1; + goto memleak_cleanup; + } + + for (i = 0;; i++) { + /* trigger our BPF programs */ + print_outstanding_combined_allocs(skel, attach_pid); + sleep(1); + } + } + + while (!exiting) { + if (env.paf || env.pr || env.procstat || env.sysstat) { + err = ring_buffer__poll(rb, 1000 /* timeout, ms */); /* Ctrl-C will cause -EINTR */ if (err == -EINTR) { err = 0; @@ -447,8 +662,7 @@ int main(int argc, char **argv) { break; } } - else if (env.sysstat) { - err = ring_buffer__poll(rb, 100 /* timeout, ms */); + else if (env.memleak) { /* Ctrl-C will cause -EINTR */ if (err == -EINTR) { err = 0; @@ -484,4 +698,10 @@ int main(int argc, char **argv) { ring_buffer__free(rb); sysstat_bpf__destroy(skel_sysstat); return err < 0 ? -err : 0; + +memleak_cleanup: + memleak_bpf__destroy(skel); + blaze_symbolizer_free(symbolizer); + free(g_stacks); + return err < 0 ? -err : 0; } \ No newline at end of file diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.h b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.h index 778767287..3b65256eb 100644 --- a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.h +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/mem_watcher.h @@ -117,4 +117,21 @@ struct sysstat_event { unsigned long kernel_misc_reclaimable; }; +/*memleak.h*/ +#define ALLOCS_MAX_ENTRIES 1000000 +#define COMBINED_ALLOCS_MAX_ENTRIES 10240 + +struct alloc_info { + __u64 size; + int stack_id; +}; + +union combined_alloc_info { + struct { + __u64 total_size : 40; + __u64 number_of_allocs : 24; + }; + __u64 bits; +}; + #endif /* __MEM_WATCHER_H */ \ No newline at end of file diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/memleak.bpf.c b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/memleak.bpf.c new file mode 100644 index 000000000..c7171f026 --- /dev/null +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/memleak.bpf.c @@ -0,0 +1,115 @@ +#include "vmlinux.h" +#include +#include +#include "mem_watcher.h" + +#define KERN_STACKID_FLAGS (0 | BPF_F_FAST_STACK_CMP) +#define USER_STACKID_FLAGS (0 | BPF_F_FAST_STACK_CMP | BPF_F_USER_STACK) + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 10240); + __type(key, pid_t); // pid + __type(value, u64); // size for alloc +} sizes SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, ALLOCS_MAX_ENTRIES); + __type(key, u64); /* alloc return address */ + __type(value, struct alloc_info); +} allocs SEC(".maps"); + +/* value: stack id 对应的堆栈的深度 + * max_entries: 最大允许存储多少个stack_id(每个stack id都对应一个完整的堆栈) + */ +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, COMBINED_ALLOCS_MAX_ENTRIES); + __type(key, u64); /* stack id */ + __type(value, union combined_alloc_info); +} combined_allocs SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_STACK_TRACE); + //__uint(max_entries, xxx); memleak_bpf__open 之后再动态设置 + __type(key, u32); /* stack id */ + //__type(value, xxx); memleak_bpf__open 之后再动态设置 +} stack_traces SEC(".maps"); + +char LICENSE[] SEC("license") = "Dual BSD/GPL"; + +SEC("uprobe") +int BPF_KPROBE(malloc_enter, size_t size) +{ + const pid_t pid = bpf_get_current_pid_tgid() >> 32; + + bpf_map_update_elem(&sizes, &pid, &size, BPF_ANY); + + return 0; +} + +SEC("uretprobe") +int BPF_KRETPROBE(malloc_exit, void *address) { + const u64 addr = (u64)address; + const pid_t pid = bpf_get_current_pid_tgid() >> 32; + struct alloc_info info; + + const u64 *size = bpf_map_lookup_elem(&sizes, &pid); + if (size == NULL) { + return 0; + } + + __builtin_memset(&info, 0, sizeof(info)); + info.size = *size; + + bpf_map_delete_elem(&sizes, &pid); + + if (address != NULL) { + info.stack_id = bpf_get_stackid(ctx, &stack_traces, USER_STACKID_FLAGS); + + bpf_map_update_elem(&allocs, &addr, &info, BPF_ANY); + + union combined_alloc_info add_cinfo = { + .total_size = info.size, + .number_of_allocs = 1 + }; + + union combined_alloc_info *exist_cinfo = bpf_map_lookup_elem(&combined_allocs, &info.stack_id); + if (exist_cinfo == NULL) { + bpf_map_update_elem(&combined_allocs, &info.stack_id, &add_cinfo, BPF_NOEXIST); + } + else { + __sync_fetch_and_add(&exist_cinfo->bits, add_cinfo.bits); + } + } + + return 0; +} + +SEC("uprobe") +int BPF_KPROBE(free_enter, void * address) +{ + const u64 addr = (u64)address; + + const struct alloc_info * info = bpf_map_lookup_elem(&allocs, &addr); + if (info == NULL) { + return 0; + } + + union combined_alloc_info * exist_cinfo = bpf_map_lookup_elem(&combined_allocs, &info->stack_id); + if (exist_cinfo == NULL) { + return 0; + } + + const union combined_alloc_info sub_cinfo = { + .total_size = info->size, + .number_of_allocs = 1 + }; + + __sync_fetch_and_sub(&exist_cinfo->bits, sub_cinfo.bits); + + bpf_map_delete_elem(&allocs, &addr); + + return 0; +} \ No newline at end of file diff --git a/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/memleak.c b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/memleak.c new file mode 100644 index 000000000..9c77632c1 --- /dev/null +++ b/eBPF_Supermarket/Memory_Subsystem/applications/mem_watcher/memleak.c @@ -0,0 +1,15 @@ +#include +#include +#include +#include +#include +#include +#include +#include "memleak.skel.h" +#include "mem_watcher.h" + +#include "blazesym.h" + +int main(int argc, char **argv) { + +} From 6131e0a499255832fad458b363b6ab74ffdb8595 Mon Sep 17 00:00:00 2001 From: zhangzihengya Date: Mon, 18 Mar 2024 17:59:47 +0800 Subject: [PATCH 18/55] Supports dynamic header --- eBPF_Supermarket/Stack_Analyser/speedscope | 1 + .../collector/collect_output.go | 110 +++++++++--------- .../eBPF_prometheus/dao/data_to_sqlite.go | 82 ++++++++++++- .../eBPF_prometheus/prom_core/processer.go | 9 +- .../prom_core/supplyforProc_image.go | 2 +- .../prom_core/supplyforTmux.go | 2 +- eBPF_Visualization/eBPF_prometheus/test | Bin 1812267 -> 0 bytes eBPF_Visualization/eBPF_prometheus/test.go | 25 ---- 8 files changed, 143 insertions(+), 88 deletions(-) create mode 160000 eBPF_Supermarket/Stack_Analyser/speedscope delete mode 100755 eBPF_Visualization/eBPF_prometheus/test delete mode 100644 eBPF_Visualization/eBPF_prometheus/test.go diff --git a/eBPF_Supermarket/Stack_Analyser/speedscope b/eBPF_Supermarket/Stack_Analyser/speedscope new file mode 160000 index 000000000..de17f128d --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/speedscope @@ -0,0 +1 @@ +Subproject commit de17f128d0ce9d2a696ac7772dec6393dc2888b4 diff --git a/eBPF_Visualization/eBPF_prometheus/collector/collect_output.go b/eBPF_Visualization/eBPF_prometheus/collector/collect_output.go index 947972988..25abdb188 100644 --- a/eBPF_Visualization/eBPF_prometheus/collector/collect_output.go +++ b/eBPF_Visualization/eBPF_prometheus/collector/collect_output.go @@ -289,9 +289,9 @@ func (b *BPF_name) Run(full string) error { metricsobj.UpdateData() // 如果 SQL 已初始化,则更新 SQL 数据;否则,初始化 SQL if metricsobj.Sqlinited { - metricsobj.UpdataSql() + metricsobj.UpdataSql(fn) } else { - metricsobj.Initsql() + metricsobj.Initsql(fn) } // 从通道中接收第二次数据 <-mapchan @@ -462,57 +462,13 @@ func redirectStdout(fn string, stdout io.ReadCloser, mapchan chan []map[string]i if enable_tgid == 0 { for _, title := range rsc_titles { if enable_tgid == 0 { - rsc_pidheader[pid] = append(rsc_pidheader[pid], fmt.Sprintf("%s(%s)", fields[1], title)) + rsc_pidheader[pid] = append(rsc_pidheader[pid], fmt.Sprintf("%s(r)(%s)", fields[1], title)) } else if enable_tgid == 1 { - rsc_pidheader[pid] = append(rsc_pidheader[pid], fmt.Sprintf("%s_%s(%s)", fields[1], fields[2], title)) + rsc_pidheader[pid] = append(rsc_pidheader[pid], fmt.Sprintf("%s_%s(r)(%s)", fields[1], fields[2], title)) } } } } - case 2: - if _, ok := sched_pidheader[pid]; !ok { - for _, title := range sched_titles { - if enable_tgid == 0 { - sched_pidheader[pid] = append(sched_pidheader[pid], fmt.Sprintf("%s(%s)", fields[1], title)) - } else if enable_tgid == 1 { - sched_pidheader[pid] = append(sched_pidheader[pid], fmt.Sprintf("%s_%s(%s)", fields[1], fields[2], title)) - } - } - } - case 3: - if _, ok := syscall_pidheader[pid]; !ok { - for _, title := range syscall_titles { - if enable_tgid == 0 { - syscall_pidheader[pid] = append(syscall_pidheader[pid], fmt.Sprintf("%s(%s)", fields[1], title)) - } else if enable_tgid == 1 { - syscall_pidheader[pid] = append(syscall_pidheader[pid], fmt.Sprintf("%s_%s(%s)", fields[1], fields[2], title)) - } - } - } - case 4: - if _, ok := ulock_pidheader[pid]; !ok { - for _, title := range ulock_titles { - if enable_tgid == 0 { - ulock_pidheader[pid] = append(ulock_pidheader[pid], fmt.Sprintf("%s(%s)", fields[1], title)) - } else if enable_tgid == 1 { - ulock_pidheader[pid] = append(ulock_pidheader[pid], fmt.Sprintf("%s_%s(%s)", fields[1], fields[2], title)) - } - } - } - case 5: - if _, ok := kt_pidheader[pid]; !ok { - for _, title := range kt_titles { - if enable_tgid == 0 { - kt_pidheader[pid] = append(kt_pidheader[pid], fmt.Sprintf("%s(%s)", fields[1], title)) - } else if enable_tgid == 1 { - kt_pidheader[pid] = append(kt_pidheader[pid], fmt.Sprintf("%s_%s(%s)", fields[1], fields[2], title)) - } - } - } - } - - switch data_type { - case 1: rsc_Map := make(map[string]interface{}) mu.Lock() rsc_header := rsc_pidheader[pid] @@ -528,55 +484,97 @@ func redirectStdout(fn string, stdout io.ReadCloser, mapchan chan []map[string]i mu.Unlock() mapchan <- []map[string]interface{}{rsc_Map} case 2: + if _, ok := sched_pidheader[pid]; !ok { + for _, title := range sched_titles { + if enable_tgid == 0 { + sched_pidheader[pid] = append(sched_pidheader[pid], fmt.Sprintf("%s(S)(%s)", fields[1], title)) + } else if enable_tgid == 1 { + sched_pidheader[pid] = append(sched_pidheader[pid], fmt.Sprintf("%s_%s(S)(%s)", fields[1], fields[2], title)) + } + } + } sched_Map := make(map[string]interface{}) mu.Lock() sched_header := sched_pidheader[pid] - for i, value := range fields[2:] { - sched_Map[sched_header[i]] = value + if enable_tgid == 0 { + for i, value := range fields[2:] { + sched_Map[sched_header[i]] = value + } + } else if enable_tgid == 1 { + for i, value := range fields[3:] { + sched_Map[sched_header[i]] = value + } } mu.Unlock() mapchan <- []map[string]interface{}{sched_Map} case 3: + if _, ok := syscall_pidheader[pid]; !ok { + for _, title := range syscall_titles { + if enable_tgid == 0 { + syscall_pidheader[pid] = append(syscall_pidheader[pid], fmt.Sprintf("%s(s)(%s)", fields[1], title)) + } else if enable_tgid == 1 { + syscall_pidheader[pid] = append(syscall_pidheader[pid], fmt.Sprintf("%s_%s(s)(%s)", fields[1], fields[2], title)) + } + } + } syscall_Map := make(map[string]interface{}) mu.Lock() syscall_header := syscall_pidheader[pid] if enable_tgid == 0 { for i, value := range fields[2:] { - syscall_Map[syscall_header[i-2]] = value + syscall_Map[syscall_header[i]] = value } } else if enable_tgid == 1 { for i, value := range fields[3:] { - syscall_Map[syscall_header[i-3]] = value + syscall_Map[syscall_header[i]] = value } } mu.Unlock() mapchan <- []map[string]interface{}{syscall_Map} case 4: + if _, ok := ulock_pidheader[pid]; !ok { + for _, title := range ulock_titles { + if enable_tgid == 0 { + ulock_pidheader[pid] = append(ulock_pidheader[pid], fmt.Sprintf("%s(l)(%s)", fields[1], title)) + } else if enable_tgid == 1 { + ulock_pidheader[pid] = append(ulock_pidheader[pid], fmt.Sprintf("%s_%s(l)(%s)", fields[1], fields[2], title)) + } + } + } ulock_Map := make(map[string]interface{}) mu.Lock() ulock_header := ulock_pidheader[pid] if enable_tgid == 0 { for i, value := range fields[2:] { - ulock_Map[ulock_header[i-2]] = value + ulock_Map[ulock_header[i]] = value } } else if enable_tgid == 1 { for i, value := range fields[3:] { - ulock_Map[ulock_header[i-3]] = value + ulock_Map[ulock_header[i]] = value } } mu.Unlock() mapchan <- []map[string]interface{}{ulock_Map} case 5: + if _, ok := kt_pidheader[pid]; !ok { + for _, title := range kt_titles { + if enable_tgid == 0 { + kt_pidheader[pid] = append(kt_pidheader[pid], fmt.Sprintf("%s(k)(%s)", fields[1], title)) + } else if enable_tgid == 1 { + kt_pidheader[pid] = append(kt_pidheader[pid], fmt.Sprintf("%s_%s(k)(%s)", fields[1], fields[2], title)) + } + } + } kt_Map := make(map[string]interface{}) mu.Lock() kt_header := kt_pidheader[pid] if enable_tgid == 0 { for i, value := range fields[2:] { - kt_Map[kt_header[i-2]] = value + kt_Map[kt_header[i]] = value } } else if enable_tgid == 1 { for i, value := range fields[3:] { - kt_Map[kt_header[i-3]] = value + kt_Map[kt_header[i]] = value } } mu.Unlock() diff --git a/eBPF_Visualization/eBPF_prometheus/dao/data_to_sqlite.go b/eBPF_Visualization/eBPF_prometheus/dao/data_to_sqlite.go index 74c07b156..907ff838a 100644 --- a/eBPF_Visualization/eBPF_prometheus/dao/data_to_sqlite.go +++ b/eBPF_Visualization/eBPF_prometheus/dao/data_to_sqlite.go @@ -23,11 +23,14 @@ import ( "log" "os" "strconv" + "strings" "gorm.io/driver/sqlite" "gorm.io/gorm" ) +var GlobalMap map[int][6]bool + // 定义一个名为 Sqlobj 的结构体类型,用于封装数据库相关的信息 type Sqlobj struct { // Tablename 字段存储数据库表的名称。 @@ -56,18 +59,29 @@ func (s *Sqlobj) Tableexist(name string) bool { } // CreateTable 建表 -func (s *Sqlobj) OperateTable(name string) { +func (s *Sqlobj) OperateTable(name string, fn string) { + // 检查表是否存在 if !s.Tableexist(name) { + // 如果表不存在,先删除已存在的同名表 deletetable := fmt.Sprintf("drop table if exists %s;", s.Tablename) + // 执行SQL语句,删除表 if err := s.db.Exec(deletetable).Error; err != nil { log.Fatalf("drop exist table failed.") } + // 创建表 if err := s.db.Table(s.Tablename).AutoMigrate(&Basicdata{}); err != nil { log.Fatalf("create table failed.") } - s.AppendTable() + // 添加表 + if fn == "proc_image" { + s.ProcAppendTable() + } else { + s.AppendTable() + } + // 创建行 s.CreateRow() } else { + // 如果表存在,直接创建行 s.CreateRow() } } @@ -87,7 +101,71 @@ func (s *Sqlobj) AppendTable() { } } +func (s *Sqlobj) ProcAppendTable() { + enable := false + data := 0 + // 遍历数据集合 + for key, value := range s.Data { + if !enable { + index := strings.Index(key, "(") + intPart := key[:index] + pid, _ := strconv.Atoi(intPart) + leftIndex := strings.Index(key, "(") + rightIndex := strings.Index(key, ")") + if leftIndex != -1 && rightIndex != -1 && rightIndex > leftIndex { + substring := key[leftIndex+1 : rightIndex] + switch substring { + case "r": + data = 1 + case "S": + data = 2 + case "s": + data = 3 + case "l": + data = 4 + case "k": + data = 5 + } + } + + if _, ok := GlobalMap[pid]; !ok { + GlobalMap[pid] = [6]bool{false, false, false, false, false, false} + array := GlobalMap[pid] + array[data] = true + GlobalMap[pid] = array + } else { + array := GlobalMap[pid] + if array[data] { + break + } + array[data] = true + GlobalMap[pid] = array + } + enable = true + } + // 默认数据类型为"text" + datatype := "text" + // 检查值是否为字符串类型 + if strvalue, is_string := value.(string); is_string { + // 如果值为字符串类型,则尝试将其转换为浮点数 + if _, err := strconv.ParseFloat(strvalue, 64); err == nil { + // 如果可以成功转换,则将数据类型设置为"real" + datatype = "real" + } + } + // 构建SQL语句,用于向表中添加列 + addcolumn := fmt.Sprintf("alter table %s add column \"%s\" %s", s.Tablename, key, datatype) + // 执行SQL语句,向表中添加列 + s.db.Exec(addcolumn) + } +} + // CreateRow 写入数据 func (s *Sqlobj) CreateRow() { + // 使用数据库连接对象创建行,并将数据插入指定表中 s.db.Table(s.Tablename).Create(s.Data) } + +func init() { + GlobalMap = make(map[int][6]bool) +} diff --git a/eBPF_Visualization/eBPF_prometheus/prom_core/processer.go b/eBPF_Visualization/eBPF_prometheus/prom_core/processer.go index 0d4ae64a1..a40b5cc3c 100644 --- a/eBPF_Visualization/eBPF_prometheus/prom_core/processer.go +++ b/eBPF_Visualization/eBPF_prometheus/prom_core/processer.go @@ -60,15 +60,18 @@ func (m *MyMetrics) UpdateData() { m.Maps = new_Dict } -func (m *MyMetrics) UpdataSql() { +func (m *MyMetrics) UpdataSql(fn string) { m.Sqlobj.Data = m.Maps + if fn == "proc_image" { + m.Sqlobj.ProcAppendTable() + } m.Sqlobj.CreateRow() } -func (m *MyMetrics) Initsql() { +func (m *MyMetrics) Initsql(fn string) { m.Sqlobj.Data = m.Maps m.Sqlobj.Connectsql() - m.Sqlobj.OperateTable(m.BPFName) + m.Sqlobj.OperateTable(m.BPFName, fn) m.Sqlinited = true } diff --git a/eBPF_Visualization/eBPF_prometheus/prom_core/supplyforProc_image.go b/eBPF_Visualization/eBPF_prometheus/prom_core/supplyforProc_image.go index db0022e55..7a9f39830 100644 --- a/eBPF_Visualization/eBPF_prometheus/prom_core/supplyforProc_image.go +++ b/eBPF_Visualization/eBPF_prometheus/prom_core/supplyforProc_image.go @@ -59,7 +59,7 @@ func (p *ProcMetrics) UpdateSql() { func (p *ProcMetrics) Initsql() { p.Sqlobj.Data = p.OriginalValue p.Sqlobj.Connectsql() - p.Sqlobj.OperateTable("proc_image") + p.Sqlobj.OperateTable("proc_image", "") p.Sqlinted = true } diff --git a/eBPF_Visualization/eBPF_prometheus/prom_core/supplyforTmux.go b/eBPF_Visualization/eBPF_prometheus/prom_core/supplyforTmux.go index 64c0cd9e4..22b1bb53b 100644 --- a/eBPF_Visualization/eBPF_prometheus/prom_core/supplyforTmux.go +++ b/eBPF_Visualization/eBPF_prometheus/prom_core/supplyforTmux.go @@ -63,7 +63,7 @@ func (t *TmuxMetrics) UpdateSql() { func (t *TmuxMetrics) Initsql() { t.Sqlobj.Data = t.OriginalValue t.Sqlobj.Connectsql() - t.Sqlobj.OperateTable("tmux_data") + t.Sqlobj.OperateTable("tmux_data", "") t.Sqlinted = true } diff --git a/eBPF_Visualization/eBPF_prometheus/test b/eBPF_Visualization/eBPF_prometheus/test deleted file mode 100755 index a11b21b0744d373da92520c1f57c6ac8ac9cd258..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1812267 zcmeFadwi6|^#{BOSy(RdSs;NRAi=I0R5anDNilT;0cUZeK@g*0MZq-Q1MEV$C<&WD zmUZo_Xl=2-Vt>|KZPlvbW;FpM0j&m6Dx_7^inFe*P%XE#f8#KQLKExy^(~B8$y!%eVE!?_gUG zJZ-i#{9F0lX2^P$n&qsg&8Y#h4F4ZB^!uZRTLrA=JRNPbp3KWXg0riT_2V`J`nj;7 zmwLCJR(&j|U^MDPF9X}j|9IU_w=QVnweShE{W{i`Z9c8X^$4(hsudBZlP>q-LuNb8 z^lU4i`TP%_$vJdFpw8_a+UkQOkI9Pa_8H!JHcY`F8p^c z@1Cv8yJze2WnJ=TcX?mZrTimi`A5w1U9zjXI>!aNlwWU_UvHIfPi{bV=fVh&H_OLq z80R<5fAMi-mNUCG4u!qM_FLuW+^G3=&W*Z!V5{Z#LVP z-%#HEt0Ahq`w8`k|8y-s2`S`Zi%YEez?vtl`M?5T%?sB1eVxi$aeRu&r>oavFYDMr zc+AJYMJDns{~pGFGKEyM&E2lc$9}8dt>3QrTk-#W{+9y(rNDnF@Lvl2mjeH#z<(+5 zf1v<%o9X!H^D-=K<}bN!#>}PHUUlQmW!K*6ojcV#bHOba-gwz{lW&@K&1K`SoV?`X z`9)&s?G^Jby!o!G(HH06cGIM*%NAce?TVr$3rAO7ICfISol|^^Mo%rh?)KX+yXMLp zuBaGeyIKT46@f3DB9#90Z~NOsDDxM56tvu(wQ!7RI*=wp{Zd6}cB(@JTSQ>H^ZIR~ zZs($O5kl;B4jq%%D1uEg?^U}^dhru^Gw~NO8pPnhMOoRpp4x+%0FO3m45jg2se2ECBKX_qZTZikg2v>^OIQ+U}7vMKPmV@8Y z*qQh(iw#pTgVe8+@#T@21JB%8YTgl1cf>c^*f6tadEGnyo_X)&9f=vCdmJL=q^LQ; zg}~xrB6vsy_lV#=t66z%@s};kB1^h7?@iBya_6GaW-AHaXZ-6gU8k-VnjVo;?RNMn^m&4|!9z79DA-_P-br z;j|ti>`oPR?<^kymJ&zziGtk=?C2D-U8Bz~y)XdC)%=-=pYn)Y_aRW#Bt7&Clcdop zptq)_#{Y@Hg�mZ*x8~z|t_M@lTVric6)D)1U5BdhAxnv3G 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 I%MJ7K`_Fmo&elk4?NldI2u`??{@a ze~KUZ*WzYRapx4!R{C~Egh}+4IFFHcj{YN4c#V~J2xXAONoWuHjbp^leHpRy&%MM> z=eR;oxA9r9>Nw-mC4e3)|LEJ=p5wz2f5(x8B>#UGYl)5E*gEuoR1T_clN?mJw}%`Q z*#6< z4LxD>|D2xizcD}V`+qP$26USrn2nj9(viq8MSiv(s>0dNe#oh^z6zV*_?8@e;4g;a z7n*6(+%F;DX>FwP)E8wGLO~(_))v{~vcs`}-F|{0%BT`(Y=}lUOyW7j{{jmNzbHblIG9II_;?I8U7_LD6>!Zhu3P`X1>HRZzr&&YfuV{WI zQ_}BBnpkMCAMa|IBi*HeeDn&ZOsoH9e}hDTs}*i&6qm<Q@m_ki3@Fmg_~iW42U1A+vu{$`tjkc8yWH4r6Bzoo9YV=fMnN zt?O7Y{>QBA-P9dolM~$nlT(A)U)bHcZsP;ilfE02IcXz%A+YyN!%qHWV`ayukIwT4 z1#LFbN2g*=ZsV&=u$%!^<*gh=80#bZ!u%SdbuJZ(OJyS|XR9iSQt&jn&lAr~;O=na z)RI8sNN$IeR221prriU<)AWPDifJ<6?__->A6-+6TD7S<6#UT+Km;z&Cq8IOZexCP zUtk${EF4EnAP`QSWD#WTdWKvFFN5a_n*fQgNjP-S2 z#ac;!m81H}eO+`AE}2Q#8zIGtx>CJhqL#|pE!?egor(}y&GuIO&k!4NWe=$L94+0X z--le}z{G0vl^u>@v z@4HXBX0Jl|+4&xd6MA|X`wd0%ZI`j%#*h3;g8Y?#$_VoFG5DXhJ|oD}P)~zDwUZMl z^-&D|>i@W1R+djgmEMa$nfJB%W4ks3wpsouPnxG%ZhjGE!;KSQ07lWqzMRI6t3c-e4s&`6*~63_IGxs%uzRW=rGWaHimS0f z;#5feuqHMt9Q&ymamn`;uQp=goxgX0p&nASz>?vSy zJR)ka{E6@Yrn-0>wn^%#imoxNEWt*H2KGF3B+mi`Y4#YYEZL%kdXUC%tw`m(P^?06 zTcPNfWU~+sTcn2>C&do;*R58}@EVS`&!K^n)XeRSMjvE$edf0G z?D|T-Zu+sEJZX;x5wH|JaFfwP27CfNq%Q(rLQ}0bM{vLRqxWG4ZykS~|9_&Ny!OLm zfc#hSU!H#Qc$$g*cl8rR&;DEfjc=LN(S{y%S5csU6K^)=ef%4l?~bdYba!!h4h0+_ zj{)3qT^w^>gn<8rio!AW-CP_G3FMwy%1^qy9N+l>FUJgH0(@UD#|_LyINfxGcH!kH z$Y?1#_O8pz;e~ZQZ+#rE81{wu@vnUxSEm=2w2$L|#lw-Y?^;*KIABYwDhizPRF#Fj zRFyCM&hn6Qrrt5C$`c-uyq~sG)}>B;7;VLXag4U&DH=0!!?BBMqMwEn4SQCcDB!+@ zL$fBzmJFkt)I=+KDM5pcAMZ^226@nTux!26!9*uUp$+S;kHeYkZ4(Hc-U#eKwd!5OcuAS4F zY?*{|F#W54neX8)PE%#=M)mI^g4Y`=oCsE`hI4fs^&C3d)kn58r<*$LVqm4CU488S zQu5KRKMK`2+q%v&$-Aq*xsN%DdN%Z(Q3r#~FE#wa;S}6R<<~X{>LKnIIN{9fz531SR;bPHGg@x0Q_U9J zZfqY%P9SrU-*0t}FX8pS)TtoYG`vafp*cF=`zCd`*bJGXP!BX!o^KjCPkzxN!|F8R zAc6#i9Zt3x9c3f9RawXw?x2k9MaC##kVUHPH{DGeE!`CZjE+ztIK*6-3_UzJcBInd z(^UD}_3Gs5gr-4y>l;4ek)EYG=;AMvGj=#~i%Be0IM zoILqw9SBYJnq3?u7y&0yHq!7Ls@EXrSKi%0->Is}ZfOGetWNJLj+BgYEfY*%`p>j<1^*iNZA&t_$zM|8F$7}qd$bF`V5^$=SJq-^6Ma+zTkgJ% zzsB7!r%l{{?o~9TBVVlk<3+NRyB!~)%vt1H6V!F-^VO8FuZ_Zq#C^`K7&T8v2M;vg zOoL{Ay31^(iT|KdHck56{#59`%2P?VxNci5RWTNI1X0d6h67HxhS*S*h!3^j-#*D> z+3to@ECi*t{&7GB(CrTIb?T)1WAA;reLvj3|8?g5ect;r`+gOxj0LEHXU~IJu7C0jxw|IN$U3bngAt>OpC7% zOW61s??jn7icUYw{Bq$^3a$Jnz$RcBFF5I`KHNm9qDq=usHt zW_K9iY5^%$jt8PB-|L`%|QVqiwV$FSD5N9<8&SMGzGZC07l-*E6lrS>9o!L$?joyYc4+JC zp^6=I!O{++rR&74&JCea+voVV_9xK~@ZHrZC;;T=w36*jrC;>*C%Rok&w zUj4ASb|-JUlef<1$PX;}6P<0UY+B6_2b#CjK`%>IlPH|_p>W}+JAIE0$NVMJ1`~2m z8p$D8cd981m2)h{A*bz){Kc<%WPZewdAlKV5(8j#FO2Mg@+r)rJDBG#&rSJFqKGlA zNo8f~qW*!{_ligrS#jrlC5(J}ro@1Sinm%`0&F&cW$b~?T#8jr7qJ{-v2!0V^WZ^K z$jqwOD3Ty8hN+___Klgic50%34uP|p=y%OsOs+{M_6bQs?rej94*7|zZi!?fyV2Xi zo&h|ZwMn**>0VW#$eMygqNd^-v#7WJ+u|{p7tPv&(NHj#i-og%qEopK{#>~ujZ51z zV>#kGShZ9bzGJqX)@9mKL&AS@yw-2ig>dX1+l4mhJvSV^Pj?3RGWWOYJe%j97u?gm zlA%azE&&qv7y#QOnAK(0Jzz7E5%Q3Gh$BJ-8^9Pjl^O(FnP6j0g6XCr4*AR~RxcV? z6C2oCV~;H`;~%bgVb0!A#Y$1oT#nd06dwITDE7-@sLS$aF@0|sV}*-ewnQ+%BLem} zrOAM^HEa{*UK1}<;|#!mVa`74cUAviGWBx^rC0y8UG-aHiTmGvfVH5M4}*kTTm6wz+S&(NPE`rGIhV!h$y1d~S( z^w@FY@Paki#vaa$)46WG*eBz((2SEIu4-a3v(_5Zn)hWWvO1T^*8~9A@9sCl_hSuT zuoqPcpklY;r*`;?HGB-3H++V)f*I19X&$_s%NCs#Lb2s9t0Znezk7|*pYydV1{ z*yO7uQgF!6)Wj0Pv%y_WMZzGh4E{U(C*3AquCT*0uWqC#9#&02##};`UL_oxWryzT zcIZwFMNdr44|BLvP0TzpbKlT+O~uzuQ&?6J(cPc@_}^$v+@!#(F~gX?lWB5rC`Q9< zY46ybTqE8TQS5Xt7VnKu9dcTrnNSIk1VK3!<$)#g@8Y{S`JL6lz>>GYUsL7%9Cjrg ziE*4IY|igR%_KcR^(eMc^qjzI^2A5lbDfI$xq*9sqA@twZY29W5Z0HF`c!sRhpXM< zzWQxscR2+l;cha#)*vbD@keyjg(XGR05`<5LF0`PO_#ZMa3+h9HbuYlH9{~%0mukJ z&iafI8j>+S2fg||l!ep0Jg+7?peEK|VJ0TSwgun4vrLP#^bC4k>JAua!hC4PkRvw`!4xZ99va;-W<6ODIQ^o9 zh8Ye=r@Yuo&|{0>4$@Q+;-r5{;$bBpy*ZJPa?RG@=fuAkh^Eb_!YAtCI?O}i=nGE! zT3A`9)n?sBH2~$5;W&gov=l=^WKubz^qkzY^1+SJzz>8gcFg$=R9=*+%0=DDw1LgO z1%1HXoAA^Fdu-94n1H>ep1Jj~R>0AJ=)gyUfqP#TD4h4RbsrL{kxDuLWj*p_O?;xH z)NpL%OEnUrvP0V9Zgh%J*3+T3zYd!c&nY08lup?>qBCp4qqaGDZ{Z@6YVC|V5L*1M zm6X5BXOm)M_cr68YU5l-NPk1sVs?s(C=c80SfQ=t)%c?heUxraa*CQ!sZi&}$sZfB zFO;`ya&*K#EB_w$1(9Da#Vov>W2g$qpuMNxgut)2UfN>s9Y0bn)oLrrnDjBsTld*Y zTf?K)0-`YMiNx!yNZd>?1KuS>;vo68x#=Rg9%wZFjamC6b|-5I?B`Eo9s@n(~7=S7k&IDyL!I9V9F4xj<{2}=VE zJ)xnMzKDw*+jWvN0T0{3lf*)bWipfIO^l7*RD%G>u!OiPP zBoRCRq)Dc)@f>X>LX)dh59@E%fq88yav_c-FVXf>P2ZsCIi(H5(2d)3)&dAeRlC{P z7b*qYoJ8uht~aS6Tt_=H%G<%6&Zr@4EnJqmPWyR|&czM-Sl_u+CQ()6o?vbuLGIiv zZrD(t$xkpDr->mno1Y*}KkRvL{s==Nzxz7D1y{G)h21jmcw7Am$T-=~wruI0))$+d zU^`XK=#6HL{VHFFW0xUhoQ!&zZTPPesZR13rTD|V(M0SAntzw0hQN-v*_bV%gKvgo zpDk9(8!^nzTA*`FI6lV~jj;;q zbM8$Dq(*YffpN!M2+sXRF@FY(;?kMYF&l#zH5~LHpXDH0rs%?z%1B3O2@1D?iU2na7a0vOt24JLsg3NMf zpV!2lR!K(qQ04LBcb2T2x?W16Xf0_jXnYG*k&_HTsO9uQj|xV}ovi zRSN-Yvxadm=XUlQ#+luRF{9rwnpXmA@)@|dM2os`^ih-T<2bc?7+6Z(1_O1dxKNZW zk7AG8&46daAO4+wXC^(tGHnk#Vo}gb>6@rKLg-lBl7s zv;UHQv*v3?yRT}$TZVpAn(RxpX@Fibh&ED`(bzl`ceph=B<+=&yxlc%G@Xv!@J9}+ z2`u@X$h|LbYoZ*ac9R-6N*G_K$OF<7hD{y}pEfW^%|Zi)XT zPj~bnq0xCivfavzC}?p{pvvS3Yz^+ye@xrpB~}**Ek$OTb$`6{_$zF3_VE%JSou?| zB_jjSoia1K;#V-sSZ~p+ikR}%)ON&M$%W0i;0>W+I094DV|2$i2MI^9fI<33b}1~#ART8 zm}m%De}nEDTqRUxuIaSs-(7WY_wJf7nC=pU=@srGSa|Y8!-{t!cZQ=|lR4Z4R+O`V z9E!YlcR223Nsa0^X9$5Yf#x>_CK@*Ov6~h9MX*dB=XiA{_pk^kziMl8zlxCj9HF3M zUI8oJcnsYg1hypqgQ}g;FNEWlnIi?!&^ZS$JemRDPDKqLXK^QVY|0_d=ip4fP`oaS zuX9dzMjx_n90Uy9aU7nwH=OsPvV}n;$~m2#e1$d<957SPEeos|YzJfOUZ-=TGYZ=? z9cy#AjSpdyn50(raUXT^UQGJMjYyUEPbPV=YBw>#H46-VZ{bBmnOC>WaY&ep$s(pY%Ziz$5kJbVHE%;01-j$qSyR^yalQfkmqa(Sv9f;rIx& zb9Gq)cqs2c>S`dKJC+L5QWKjpX#9}m!|iKXUNyjeCLq?ToI`>6+UOAR= z^%JJ6(HE4={!O_Y(qLtfsNJ2lPO9o1jPnk#O}y4>!oC=1iNi|wpBZP) zk9<0u_cG(WhjCWp(e~tP2qK2G+A^di{4ZHQFM0hM(T%AHqTUnEBb$9|g2HCRsh4i5 z7LM%QMw9(W+BkPuRbWMhmCqcU>Ur-aPyrZuE&I`Rq3F|~i~5si(rot$-|O1wH=pu& z8++ty$u3%tz|{bQ!g%JyzhP|VZK-^1e)gYz(TSe-ea!%IpK7?8Qdz>firvSI{Gmq? z>m5%sBKH&bbZ0`T`?`Rz{B;>r<-tJ8NIv7=b)@*O}!4v zB2Iz0SuAn5wc~~F{#R^{Y{5sph(az5)f^xK7L& zQYR^s8jG0Yu;wn#@g=8116_c7R|bDqc(9|dP2^MBHpudkRMtH@n_A=k=I;;oxl>B% zh(II#Uo3yrMT31yTZp%_=OS&nkkWCs+0Z6V6ZbQ84Eyu9j%l*T1B*X$Xr%F1_CDuR zzbT%p6RC9?G`dBzP|RvkF&k6d8odO=L9Jy_!THbpY_Nx)iZ=tzTPPVje|F_yUu11| z#q8;UC5!n0GlZkgvi6O=92NwzRDOy+!4@x)&ACm1E^+@gZS?&4uVnd}P2V~3dg@GI zxLp~oNK17nxcLny@KmRi(+E*vk)Z|_nL*}c(D^5D$myrJ9mi>+oB?Qj%89dl-H zzWibqPKbg2KL%utkJv_ofNY4{=<`;yk1jkQClIz%N)Nu2<=sRP?D?~}jeqx%u{aOa=-RhZxTFPaUz3*9n@^nfq%K<`qFES$P0AJj04^7i`TNUX5_0+Go14de7<&Mm6zcs;TQ9y8pQ6;?oVbO?BIbNJ0sPB)gt%R zh28+F*#aS}C^;2LqHEy1D?5HHT1)6!z4&Mgh!4b1)fmSXZZ8eT{XhKA!M<=sdjtM7^`qP)w44`atlKD=87thHNbVk3$s>{qD;*n7?2wq3bw3+#AF7cnN8s?DX z!jJ~(^_bj}pvm^a?+A(B@ycNgp@u(DQ9qrOg|SKHq!63wj7D!>p!vzK`ZM}HovW)W z(>+TVLqZUx_}5oK0;74d%ZXaFW~t_hAMub+=-`!`py2&#REjTKro30>DqEXe%McJ5 zJYTEUXYggrV0;Pg*Go`7)vzt1hT5x`Kn6FJ6mq`~Zunr#Pt^=oVN;iT$u}usJshNG zGn4)o%hI#hedSJ%0FuLwH|!ZYu;c$LTJz>_Q7r#QpB(IqCA9F&NU-VV-1yb+RqSjW zW9Fy3QJz|;wAB4{WwtMtzktGqT`s*(UjR`NjLQ6FxQ8&(1@1Jwb97+d>1i5Xdo;^O z9R<-=_vj(>?uKi5XF_j&Y~KxWck_n$p|^?8nQJR}l7-&}3BCG4n&#ajccgpz{`uD~ zOow(y{z{Ulg3Yf(VOy+y%bcGyKq?A!Ux#A$<1sA#E7;P5tAJTK+{Fr7dEHn7sv7)m z{+4VX@`o9owbdmhAmGkV4EA*-BfGQIU1odKP`3t(+Hwei20Mi4sN)$1u33t^tFctF`tS#_GS1;bfvnE9}#Aj(v9C@a|w?FX9PX+@I zuGPWa+hXVcu3LE%6{QA=5{o!lDf1k0 zHSoo6@s2c{2X`6$;V7wIzHMf%%EkvS11s!B3Ud4cMC)F=)S!lZnL>-yTtqkWBR^+H zq>TL;59?8x(be36e*y|PsaRSGJuRmP?zD~QlqMxqdGcG3y9Gzh3Dzz!&8>MUFn^N< zlf7}k_y)J)P~Bmy1Aq4#_yWyK%=>OITKLC#fR+O2Ljtta0(#?Cs-vw^cgHr3nPMd> z#+Rc@fis2sZgR`{&H)YXPDA%Tcg(<4NieEon_c!=EC+*8LPbhVK&H( zZZI5#16XM1P<4GHqC@@JVjClfrqD>o3)g&{`^Se|B5uHfBxv}3_ZBT`bJ zgi@r3{8+8R+HfHf)&^l{;UeU?wutCe2?j-b?WC99gcN8-k6+94SA8`zKKmQe<8x_7 z6|wLu79=B|#R})03(p3wGTc4&<{IY_dQpxOAD>0=++BBvV>zqCvHW+&$kCUjATwVO z4~(SVDY2ZkDn(E|;R_FfvN{_A_$zSoa@=3*Th32XPpWgpGKCgli7ilO!g&5|YgowM zxR;JViUb-;evjT`YTz0`nA1k)P0k1Qwf=^04EAB*@QhkNZeS44&>;S`Bg<#v)&!5_ zw_Oj?fA{Tr6fo^#%M6@%q5jWJ>#qe)EdM8K6vDHzrZ7>Z z{N_@dKiB&I{xIdY;xO)%wEulx0{Xv&LhVSmLMy`cMOinEx7 z-(_6T_v`Pa?=p(G{Rv1CV+(ryKcM*8zwxJolJ0G`_;)X+xE3IHmzHkB2d7e!nyOFW z75Jcf;cu1qzStep?R}rj`(?a$=h|A&3GitSuk6f`-_soj@~E{|wX%wvS7=e~&;kx5 z&UfK`i1?nhP3idGQpHD~Vj58Yp6kIC>F@bSX&RHmBxo9f{)eCKYM1O73s_-`%zf#xsq7D*z%alCL+?0&{Isu`zh?o%~4cU9xw(YppS!Ap%4&flK+ z>V0R|hlO4I2}%>^fAFh=aWbw?gqLgxED7;Cv}8wMNsxI&TWc#-55_ ztTRHul&=vNG1JOWugOeGHYq-j=RY>8z_*nBDCw6yYE&8bjN?~GhUfG*sR{_0sd5u_ zRWBuCEd9ccaCdTNe})hG%#?^!-lrvD(Z_mEiy@|%Ri4AZ|e?l@>Yhh8v)Jj=gd9+|hZ?WVnfU1Vv3=3f2&@mq@fzc3C& z3>7q=Uf&ZDvwOC^#9+bn|CXNZm-lL)op_aJ^324K+Hva!k7?^u?+eczQ-DXSncK0h zCp^1v>5hx!oSp;Yjgg)I`CaqhEHaL0vGh2Ub2bhzQBI(F9ZeegGTcsd ze2uxRPbRAaum1r|7{-|R5yEHGqErh&GJ2o?jI zB9$lHuWI3>bRad{;&0ayp@#=%V`jq!qAKgD^STXI^w3plr1DRII9p8w`7I``sPtp@JP+?YhJ?-^l>OVVOKS+*lcXOfG#7es$ z7ryjGgW$A^L4D#1q5$m9vL8^nraNQGlhiMI)gO*OTB1|eY>Md{sMNGYh#PQ+LD76O zu&2@!ck@+BM_9 z`H=lB9Uz7=Cjmaz>1{ogGYy~S+G+Q%XNY&qHWbnLj@*CDIKzx)cAMiDM%>>1HQ-TgiSW&L8&< z6MOS{A882ImaB<+Z#a4ihs&%jj#R$H5U|^^Ci)lm zx9L)MQ)B`EleFfuL@3-D#8mc00|3E$#DTI!4?okspeX&@`o7T|?lmhl#GOqYy^f5N zpP24u=+AV8@vXC?k-<#rEc$U$V9B#yKduybK?7dE9co}39FCn{6TLAv96dSlgcf4> zM|M#_;Nd>pt97>xv94RC13<-5DwbL ziP=SoRj@XE-{&uHp_x%1iB$glJ~|v|j_{lgv=xbdm))&ib8uQiTd}t^w6P-87bLG! zF-}Z91$N7K@P|K`rF`jGJUE#LhX1bOq2>Gc6J(HZH+~vR(Y-_>SVpAy+Q%&OSx3CE z$9$}C(_FIMba;8m%jWlsC9e7XUCDlaBb5)qlvw9)lJg+u6_zLR^HijbE0H~?B$|$Z z_S1R5PJ}Z0Hb9r%_Tug&ib58iBeKMpUAX69lw0%>#U*3zF>%nt*!YPdD1Y%@Z-3%W zyFc+QyA8LRm{^ps{!Mp&9%vqxf~!DUA~S`*qiettu7@+lT}(gXh5eR_H#E@+VzxU1 z&9B0C!DIrxF3E9l^u{Ynd}qaGvS2WF^NqJbnjJzoy}^$x{05d_ALjOgf;s(@Uo_vE zvJVcPiEfn#Y>@7o8k=jru!5_&&;UKJ^gJcUYtF zja{knW{HLa-?~4~*I7co*BhMFIs6T#u-4vCPQI`B4Yiy@8o!~A_z*oo=;1Fs zMsKJ^t82I^u%d2Ay3#4!oD8dQB5U42D$bpE0h8ty)4&cVUS}GpGY!<42I@=$b*2HH z&;WmFfaf%TuV=}wz=La21B`jh@}K5if##RRzI2RqMO|6Lq$IXSUnW3<{)#`TL}XFW zr?Fb@k?np%|GOrc@eef1f8z}#h!=yH6?pubb0I1$WQiHlSaI#HPmK?(xO0d(HnHDI zi}sa5d*E?~<|sl?;PH(F`UjSdSABR-VY&y&*zg*g=?-7)jCu}H@dCmHJ5!DDST6+} zDO=2lH=Dp%C!U^J&6fFc-=dL?60eiGt~cXY{Pa3rB3Gm@Fiv;Crkz3#QYClR-JRN% zLc^V_L)qmdY*_fBL*$?ndHIk;5qtzMykk}~%li#fKcYr+@r2rq`wKOPiC6!+x$Oe) zJKnvkU*79GA+b(3k9jwJ7az)u~s7@7t^BA-5bBr%LC$Upj)u3kkOltd->UcxxT8EQmeEfgQcSt3TOYA&#j)C?eRYZK=%{J zt=G`U@b{~G_VMaITXnm&**^D1>J@+4b@;d-Kdr~{{6!}r_C(QUG5F-32%N|5M&IK# zwR&Q%7Ixq=W8HvjD{o-qYuVo6KtkEZN|8?>l zRPlxTD?Lb)kP~ZiSmfk7#UC+E;o}u8trVMg0vDpUd0RdH(z021c|6{(i{EkavMx?Y zzZY%H`#z7gDwvByT+Cgbx}WyP+(!Gx_H(WUXktANf)sE^*#}4a^T24v1w3$Lhv;G{ z?=xMj$yFEgd1SgcWg1=l{$vd={LkHmVQn`PzYA$fs<0dr{OBHg; zcxswmzP2hTXBKWGcha}acwI$U&8lL)bB8_tKI3H+M0Ysd7ZYacs_6(K)3&HqmchTCL&YZ4eJ( zRyw$RzmCr|`j2@k5O|q8+9~zmaZpN3qi#NnAJiWB9N5#WfN1)e`oGGK~v}4vwCbj=FKSGBz=2`Q89N>MR|FD%$Js1d2 z@c;1TzSdYK{`hw+a*PGSg#Qbl;9%elGeAGGyO!rD3EZx}8?v-oL_sRw9blZq_=-gQ z5W0K8&1Qq{ul4Ph?6;pakn-)wp5H!)uTvD5{?^EsH}N^6C&&96?*fZ=y_f5?{@?u8 zx^XeSxKpn}@>ZJ7?lfxfd#cwrPQ;i|T(jhrMvf!CB-iq{Rrk>k%L!(E3RG_dTj|IiJ-rpi-(BSw`UE4*xhVtoQ% zU7hk9GZBee^CFc6JoPnTJhYW*fxOX#L081`f3`&CrG;cE%ir*8**|0-2{@w>2}j|Kx1x3 zL0!%JSm8GpVJeCo$!hFp20wLT%)1Oeb66?8-hfAiTt@A$m zo_pih5Fk7KB`RlXjQKZzQ%K40;0KLvqyQ+S0d?AK*i6f5{3$rKV&h#OLsi`F#1;i( zf50b*3Cq9fgu$FR*xvABat_j;<-Zu>sOYBI5>%1YZ>{Y$d1LTS)Z>!OA8c#M|1;QX$=|}?M7#eWl+8r#Z1?}uyK;+gG`he3jL(+_ z`YWn1OHmt%&L+(lT?$ns+8?wK6)T=k`~(P7z741b3|h;nZst4DfhF#vlY5~})UqJk zqn1m(xiK@=qUz&QnV1PPF#-Rys`Pw5G33o>QD6{LMrv^8D$iWO|F$&btL`hvWA6UE zM!{Hd|0233vSfYUr74jn%xd~D772RI#t{C9aT9l^bY_k29oeS|moS8&(5pRi55r1%*bp55=0 zbElhR90mXCZ`tun^U`hW z`uI{6PJ5FyJN=_f|Id3Iqau79QY*;vNNv}~KIjI&t49tBEFrZYj5n9s(;I9m3SWnv z1(xLS2K3~M#Sx!7JXW}YOX9B!*YcZ=Pa6dD&o{Fq{XOh_34?2>Zn>`q)E@o;z1?3$ z`xfrP3(!cN=#Ub3@uXgGBk!qL!%0HH6t6OO7#&Dn00I;4m$9H8mxVDo{e9>aKZE&E zzD1{fv6f6Z#v+x^H>h4>I_?(&-KDrxbL^%1I+v%_x`qNA>THX86MK!WY%#5R8T+#nonb0bz&_Bu)ohV zN@4Oup1F^dWgCqXP`A@8XF5e07x_0?WgR)3&6`^qg~z>KYQ+44qTC}>J3YN}%UU6*R|!UG1f zAqO6SuhTs^-Ok}6WrDpwC?OQKw+bV0fv@odCl+<|2*CnHN zfAasef^93Jg$8CsG*NlR5wU2NMj+;&%da-%dEuIU5i0`^wzl~1WQ1D$v-rzeJRA8H zLj1-uIse>UXs$hI)+{S@kF}STqucsoX~Pn12~`<_O&Ge^h7(f+i)k()+KU$^UK8P( zx9P~jSfW+Kh)3x=f_?2h(y;rkVq*KOvlQL<^CT}acE@!p8ZW$Sfc?VUG7PL_Ugn7S zgC*vnX6g%<_38s(eucPZGmW1-=B1J;0KwXO6!8c~NbV3$d&vTVmPJ zggN!bX~$21e-!ai($}kBMEZ(-(e~EPWU68&4}gw27{Qy#tZ%Dswy0@0lh_v8bUTHt z{W`GZMpi9GC32@3mE}L=C+`2*XYEXf{x9v-w}e~D?z0|4=ESU|ROaS4vqpWc)wkgr zktGNGk0TIQ(7i4`c(e&4P z9M6B@YkI!gQGl7MLQeXDp6tM59$4XDr<+**XjK(I|4CDL;96e%LNDU^Kl+vmEt0hjOU=gj;a`q3K3Jey9Tp|Z)IQy1RmjlbKhlR4xA99NXa6Rs z4p3 z%euN+>kZGTJ+c^W55z~KO2CXpnZpGCOyqh@;7`ECTB0ny{jT2xet+%)Z|^q1cib|Gxpb9#Cr7Qmvk|)P z8#oVF8a-`R@TR+WJDD-FJNpr@V~4v)mluq@EG1-oc2RiIEB(|so}jSm+MiqdVp~%` z-J?8%+mTfNQ>(wHz#KOQ*Jp6J%Yy&)~7ZYwbiM zw9kt_ZSzP^6mKf2x(Ys>p_)T%CQ5&n_}>R-WBx4+m{ zD3JU%0JYO`2?2AFD{)R&iI*v1;x@N!iy}II4OgjH;1%&Ut!AKxuB8CbU$X2@?(>iy z7C9*}9yVq8Pi$0*DBmO_Httay^*K?m6eMh}(lT4+7ex75+SVjtcaW}}78pVax$v?` z^J8`<#`oc086Vg7Gfb9NqBskEoa+oP68}T0mZjOz>QbN3$MG(8R#$4fpQ?VC10r|v zz(k>=crWw3pSp+-@NbJtKX(V|?)>Yg3ku>tT>1;bPq;_UzkYgyOJCyBPx_2>dp^Fz zPuI98KgIQK;}+6w-$#>f0*tqzbYmjK#yHG84l_z0KVffiqd!V{wh;^c;jdZBw3!Y< zVlIPA7YzpKBve?GPzaCuwa2=Bb2@t^ELNxedgcLk(F44!$7H@nSPW@BYv(x|ezf2T z%CdAyl`m5I@NM9=&QQY_soX_qlw~rxI#A1}{@FS!m3A8~htr+dbUe;=i&qvx~Wvk$~9Lo&o61Ze{30xZA0Gb)!Nvv9) zN3-T#ECV@-xQ}*yAfp61$h11v+FWtA z0Jb`CD{=YrZuLu}SpoqDzl<`)j3e1vwP=&pEW;uRTov zBBlAZHW2QqeSDksC?bV$P{JzmDNg?qD3Liq9Avyl2p$jomJ8lu z4Xc(9p_Da$9J@#B8*}R(Qg|DbNnce(lnam?iSXNc3Er8b>nIi}opUoo3^ttxd!UPn zk>y1ab_bjK5+P&3sR@(hw$|at2ZlHmNrTm(xKh2j(jI%bP)FC+PfF2!4EJ7z*y`Vj z-iTFRa7C(=HMQ_bWocRu$0>U&n*~PnA{H8g)e}13jFp~Bxa7lN)5#DJ!KZl9RRtqi zxx9-hnRh)s6f*4eli5fZmd@of-I9-6=iI{z%;zPCbRGHK;iIvJbWdpD>0@k>YUJ$5 z^Ew+HXBH3ivYg{CbI%RHho?G5qMJX#ZJ+UkhQubP8gv1Klj(8dOsHilx(-#{tM*t; zLwILpu=Rdvo658x@ne-!5o6>NktvsTwv;0a=W}97Yw&(+>AL!UJ0awB{6~37pbr^p zQDWp4EoLzw+&Uqa`x!xtpC!3F2&Uy*-S;nf%P)oVu!PhVuglO+C?O4P>|skouJ4RK zsetqsN1z{L*9b53z^|d7;__`CHIy?k1+r8`Rc$+|nexo5FI(F28ip#4c8vBne_y^j z-tBz<(EelhkG`bSnF1q#Fstu&rR-!EAmuc3Dk~!Fjd$s9Nq)-|u>ZMQ3e7eQ1E{~YtNui~{?(+I39kMruKaNl?OI~E_Ay&*mo7{U zQ-#Zk&{~N#T9mP){^LtFQ=@h?yKA0J-GZ@aE>Y({{;k*-$!`z1oY`Zk?i5vb2h}A^ zQ*oB%Z<15GOeqg0jQ*FC57#kMK8*~E#tQV{?3E!cg2F^w!;92Bv|ChSCVt?$Q`khW z61LyWbj^6_m1?lJ`>J=aIY^~mK+>pJr9(1TjKeGERziLxq7^ziUa@Nx8((B4SCaZT zeN(hu_(8f|1P#lr63@TL2Pg_H|28ECA*Z`})@A{}akHpkpxtYiiM)+3bo4XdszT3^ zeitf-xoqPzG^&5>?mNgSO=%x5`s6c2;YmI^e2pTbxoi1h5f04EX(wc*s#cHGHbSUqT-ih781^8Ny_B5#B-k&6eOEn%X@(1vM!R1-D+9QMCDBy2~V9$$Va z>pXvcW<*MVCmK5+gAkdd4J~mqQ6DMYd&6-Vy@Ji}LTZt(owtzg$8x4D&?w|72DNVU zJV;zDH%O9iUs{rTls*%l??#`q$vJ~>bNjco(Hz50Ih0TR zqnURaT{BamBkOGVDm^)tNS)wj+iZB=0VeEAHOWX0?vt&%_j-*a?8Sy5azT^Idtx_f zfS5mQV*V@fA8;(%^>}0ksAOW7y75*E^Bl%7aZg$4X6+3`dE|1k&gN7lJv&dmiRF&x z2VTp)08iPF zNWrFGS;&^L2DR*e`zu>Xa5I%y4*w*-e$NzBzxh(>ARc@|g9QQVKrW<*{o*yQ_~uRN z;vZpw;|R)rXo-1+baT1>EdC9De(thY>zeqP8qL5*h&|KA4%M+;R7w2T66!H^B&1qQ z(4~K&vqCz3uF|g|A$cPkcP#LuCLsz7B$o4l4O#(r?$b65MlbQhaGT$o8&u zea{On;Ea`~AG-fmEgr3zea_BAp`~WWea@NT*pb|82u%87Kt?aTQSAQRdRDE5z zns{#^MqxQ0C=|>6(Ebc>*H1KOoBhe%&QGK?a=mEAK=2#=x4k-+vz&wqj9($Gzb5GF zEKs3z11I_)I<`bU>u>REJn~<8)QfD|*!)nFS`< zXq(Cz4s=Aiw1dTR2iq?>D!~7Va=is`1mKW}bKck%?r*^up8rA9(O%=~jB)^))@!DJ zdt45>;!2_6_v{I^r2SqF2g6n(K)Uj?0lF*Ud}PdeDRm+n$NdfIjUzA(TF-7ZP*mE# z6z#jc_$ihi%-<~b$3c*ef3-jUpc}toTXK)Cr!w7p_hP*|*D>sCP=smNg(O~S!*+P7 zY_x?7PtcCUHdL%FA<Q##?U$SeM zw@$QB{(^9d4YJH`DxQp(*T5CUuE1pP4qH2}K(51pE{y&i?KJBn)e$MZ+$M3L%lWk` z%d{!lXP5A)f3~5;N;{e9v|kVC>sr_BBEqR-X|_Y@-$JVjxTJk^FO>i{`mI?M7(q^ z`|xY_GRdD=*Vz5mjchxr2#Sz73xkcF?$l(D>6{E$o9oRo3@1>#L|e@nGNHgUy~n*# zUjRReHU8Btv$tCp!K5>^$TS^Mbh~Riv}K5iM=6QDLzA5 zzq+t;#7Zxobr#N)Sq&lND|)Yz_tR@IlhE&7{Q6Nh*{Id}l8PbVm8_mONgeJQ-I039 znq)uJ}tX-xahTF=|?c~bMq_0!YDc8wXeK7C>dx<37KX1fW^ly+i z>VV%r864BEcR*JC{>lE@s8)grD}R~gV*xz+%CRllj70a&N_#acE51IzW{i#+p+#0h zxK1uu{)22%*RY_Ka7ljKgb^~*h7d!pW}O9jJe`WnJ#J_GpL5cz%I!qBosrr=JgA+i z9V6NV;j|7jwSx1y?Jw)5r~B7XKO&>%V(iSrTvNFZzXP^A95oo4H>$&%R#k}*oOcUM zmY8fRgrblKDMWR+Ej%K_pqK5Y;d8qB^zNc`pHyead_3CkkBWz^GyQL-Z*^1C{R4-` zwr~P zmRn)N$XzDKZp3I5ev;c$w*rf*@2qO5&qr`9mH`EAn{0Wfy=>KgtwxU!_<-kF*Z+AY@xqRa8ItTj!X zeI?p4KWA3X&z#dA`AID(M6!fA`Kf2l?^Tm^e(&0lke-Wg=MQo5i_Xugy-soYT+!tT z-Q0mtV}WgmEu7TD>t(SYN#ar-zoauUF&a~Ny6i`T&GIpxmf;4QWZsvS<0g{3q2H{h z1(HwXGh=2n4)vHQ)`~;b^9m0_)ng8(_tsu|v%Mz}tIrn1xW_xrE7>*cbZ^uyZVIqT zdZ48qP2N+3(9z3ENKTTGv7mn}XAp+dovjN!ZxzMv&6EFlobQ%=I46|$Yf5|ybM{RY zqt;c9TFtEw`}lH@%4%^M&_ZQn*DT2Hz7KHdDzfxvl#iRCv1=A)%K}n&V36Z7?$kRz zH*U^qPLJD6I@KRC`{V0})_Cx@!~drlPxl%<5{IPQtu4{PTe^a2zbts8{Jt zTjSln##&7vtz`*h^SVIY2^MSzL+r23KEzV}W^*%9&>XvdL4PxlN%faG&Xje}LQKGP z_-`yRdrT+Y$TPQ{(sN2JF+}!#L=KB3g9rC^`w+M60yu=NuesA(PUZTy)f=(d`vYb5 z52@^4ug}|-R_66TErDwv96@xj>N7 zK*H{CZ_1Be^nm^Q=D(ib;DRy`Dh+>;k#*huE$00XT@M#C0Uy`NqIv1OGOQ0KB5!@y zzv^oTvi6XHd}Zae9lXC}t*#je?=r2a`A)-uUUP;v9LTH<>WuK)Dwuc{Vs`2R5^9c4 zUDR-(w@X^ol{B*9KvwN&%SJ_rWYO3nDt{@AuRcQl?4^nH2%d9t8hQcx#WoL;lkV6VPk5n8`o0sZaC9q}A5JKmVKU3VOGL%&*yA0jH^Yz-K6;$^V@a$iT`_NC(7W~)BqGjVfd%vjZ}E=pE)(w z6G**5-H%iEzpS{(uh_VXw;ob4m7c9i@$5W&j4B1c1AVt~G>YXM*s2p!;52>nf-`7vh2>oDpNdx@!<|k5mmtWJw zu9~(`#;<9eibn&#;AeHW??9vbx!?Un^b=|66%9-zv^p?{zicYXUqvwP z^@`@)sXVb9Pu~MG<5`*UF!`^uv4Qgx+bD zr(bZPm|uF=pr4ZAD`$o><`kCAU(lhRzCy z>Sa>WKo+ecn2QJeTlyHm+DLoZ9fP>y;fH7~!IIP1hU8NrFzo{0rf$HYxyH8m^m~+; zUYK%Z7zw*?@phk`RMK%-gh)=-lg$j z4ZIJ5CL(9SByHlW$L@hOGEe4f;JSbk!-1AV^E8BX|D<*)Sn~>tMMoEpm(6!p#ujg- zmCD#7hM&op!^RdD(PeP|d%_#4redB{if)K*G$oquOhBxYhR2(@hc;r*3NdF|r{ls5 zuVnXqJZccQ{4!AcyhB=E=UU#>)pEXVdHmrmTlyk-%Kx+Vq8_c!RO=7YddFm}Rg-ce zV^0%0_u~F~ph*t(DTt1~I^hpYEKvP-L zR@=Wkwm_&~hV7SFyi{*Fl5{69tAFR5WzUc0n4acZ{16v-Vxn!qixflYx3h&EYLMkQ(Hfg$Aee5wWM=9&zpYXE36oQ-)L;#H zkQw=a=x${}E-PrD67za!40p89v^0i^RZ7ZlYjAa>m53Rl%vguBkGQ{2>==c&N!O119u)WMw za02+K!)SB^Z=n8ixP~XWhux*^%-VCJ2ogKFJfnf;g{Joqf0nI;Ly%yalnN3T+ViUI zqMP3&L-G3i&_+(lUbY|bfsm_hxNNvRMioQ;d0;14)L zTngc!RlX9#8oG|%JJV!smDv*!5Y`g-akyWbfAKR^Of9t?w)THQht0k|u6C-kaFFDe z-1(M2WuxK@p8HozuphRi?O3BZ9YonmmZ_52$54swhcS6fR&U35^spZq%%0|e@J0h8 zetx4kP=ta9E`%FC-^)aWa3ISo*&JLz-|76g2IYti`+(qQ@AeR~V?b;(4Eq4JY3uer zy#C5%7zt2$`POUvnps8T+o(M8*E2YZ@5C7hjs;S^bNi-3s3C zd~wJx8JI9t6FfsRUmq(SM#D^ckPxrcJf!CI6_&DUbi4_r#J< zgUwr*Tq_Bxh({U-YY;ONW^lHf;4t<^i-=B@C4}QM+272ocJj5AGOg9ZfT_ahD&g@A z5W0xR?id(vF-!d8C2{)=Dh?0>v!daizL~YVD`RCddGV{}1_2LO`ZBNBpf_1L^ZuqK zxb%uU$dOl>*`gP*k;3zas`(=uoI>27x(Mw|&NXX;d~>yO>>kV8nF6e|)T6L^RGf;N zA5G!r3QsqlZK4lBJmP_w{|${0n`ri->0>x&n=^mRUU$dC_N&N@;0yZ&KFv~B`FS3vN*Oq~{ddc3 zIfO^0lTX>VFm_lTCXE;2%!qTL5Ye5>g^s4ie)yW7{~{a8f6bqnOV}MvEtxSd@QtU9i&O#LBEc^{1jaG=?fEARWv!ev$CXD%_$XxBi7V01&K4r0L~ zEcE{Z!l|OzXC@ZsM#FL+0e!;mta&K4v(RI?r@|IY_k!PFX}?DBRT*nQPn%J(catuI zRM^WP*R}7i44$^eW|ZXdhyQLRkL{8?cJS?ORNu->8{i$`$TAyAy^}E#p%x{UX%@BrXQZzkeZQKcx!@pqXVG#cvH9`dBc^o4V(mR* zK)&3GBw2J9D8p7F>&1o6QLN~m8*nH;swy$v(AtCcMoK51uSFanoPwoFDBkSGDVYo< zo7Zs9Q!)CNsOf7q|4}PWHAI#P*ctcU)UeFj3e}t<3Cnf3MmDeX7usNB7+iXlt|Ycg zJI4Ga&t%gyOF=5yAjKe(3RTa>W12tScm9XansU3sbQgd3&DMbP z+|IYkV}V=wC@a|+Y#O9p3p!e)K7@VCw9Fn{+Y8v<$w<|U-EUj>t<6MCJ@XdztKY@l zyp~`+!_-pBQc_P2ojYnl0a0TF$#_hSNwWLQxfvf^xdyzVC30r9AjEAzpg|CTLjd|>Zrsf~hF{eLOP|OSFtmlR;?W+#yn1nKc!~hm z0u-K>`af~2t4a_=__4?qYuu0joQ(OSSYNsO%bWxhadhB&mSGp z;xKW;;1&wZ$7r3%UcZ4|C6{D#mD`nunHbg%q?{=EM~+g?b14PpZc@yri}`c3Q~BMc zPooZH`oVSXFVn&;2o75YKn%y=4#E1&Sq9TCL*16 z24aZ#@LbZC%ed+fqxthXi#@|!hcpVYpv9p=t}HA2XE&zDH~NXIW-JHJMtR4rLq%SDV;O)Y#_V&Ql8a8>bz759mx5|1rF)c zay~FSzXzR^a|s9kDK9w6l8-$GB;b7NlIVIK``G+BjD;{(--%~5zG&`no4g)(|EmMJ z>ZPJ%2}^JAZ{589-XC+TS)U17d&Z_KN6x3;QN2u=)pIl|1yhh{D`*>NSDHQIC8Oe7U3Hy8GtD|auOfhJ$6(Bxg%l)(NH3`3Pi-_d6sUSo+HL#N2Dl|D3?uyk2 z6vuK5Hd%Rfq&_dB<_t6}c@F&Xob|8i4ECCB*UpPQpDY0s>2|tmiPRTn)QqNZVY={- z4=rqN?olw^rLqR3Il(6DU!38pN9hW#I;?^bJt|0^YLA`Q=gSXb$cw`bivWe8|5rPl zu_OejJp*VG7_judj(7>>g?h?w#$H1Ra)h11qYg7ity54rl8*vV+$wUaT`wn-I?t}* zFwZ7%Np@l~D%^Nr*P38P@;}I@Yao(F+a_0sEfq80Zd3xIX|)Fr^uFea(K1g33NrZw zk5{n42Ju_L(V+`5Y2a7yfe*)%%`CW;yBlu(%YX4S245cQRaVkchg0S&L#bqW?2@dB zncN>JFKG$hKhXl`%Dfa5*!dNu`^Vezl_d>fnwztOK!`xyU${inGBH-xk0Vtv5fic6 zo7lX5p8R@^L*(}@d#uso&0}`T_P$>+ZDnP2m6_ed3-qyYp5r2s^L?ulXe*BxPDuoM zJE-yw;n<0>3MyT5Z+6+<&6B4gI^hos90%!oLcJ%BnYpa_)S3T33iRcaZn<3_J~${I z24#kz2hLpC-+%qP`QQEXc`}1EO`bS0D{vouOD0r-djz`>%Ki&-aMFEtt)KD|1w{_b z!wY**f-HT+1N(kXs=fU&+op;R`~r&vlH#jKvg}p0pHyugB+2w?Tnf zroj^V#L4!M7&&xm@88ZEcIAgiZ%O@LS67T8KrZXQX{hT>r?h6aH)}~H z@$6`eTR$R5b)ckq*tHTBTc}nne9eKI59SRo$GzqaH^7=YbF9K z^D@&2|HJJpN-GI_Cq&w?5=33au_!hn>`lYdG#ZlV{_e8ohZMAhY<`zFa!;{?U$99h zbty>rk%(~2qN@rxxR4DTY`A8 ztlu3!lHJ0h4z~;6xDwtn_DBmgh%koBOLG33sJgSPp2b?f(O_oq zkyZpngOlF_(Iq1?rMZ*B{*UF? zD?$j>YKBdYU*9=7dR+)v^FJ9$F!BhMUmC0I2+3O}>~d|XIjfdx*|-Ln!oiMyOqG0i zsG`5AAsBGi6P>+wSQsHZX*WAyScR-~@zOl6asN7&NbrGQk^wS3ZqZrpYylP`ZV0Z} zkvWS;CXia7u#H{B4kJCrsCGwxhH`b<^}$4t+6 zD+2g2yB47&nH?;w0%m~7Cr|m`j8u1Aa|EQSXIVMKtBmKG%aP}Bk+yGnZ1`5f6Vbgy zt|3P`=E=Q3^g-c3+LA&IZZ8`E9f=aZ!;0w!sKAkzaYKN*8iz?{cHVb!6I~ptRVKzvuac9%ze!%izhD? z>H-+~Heqp>cCMJk69EV;!i!6v9(5e=l%fZEbTvQ0CM(>H;h8!UbKQ~y!3WQ_E$JRf zr1X=?T7}1(RkMZSwqYeO7|_8^4VDC*HKQtHlaN6pHfX6CJ{ixemC?&te*4|>+XZlV zBW86d!TQ4~M`!K1=HA)%&9428-FO-+ks3 z$e4}nv3}>Bs8*c42KRGJ6bYOpoMxTm!RhX#MR;loUZvU&mIn*Z=krp1x*`IxHn{G98GAm^(A(-R`EnP7&~yn-J7GZUc1WQ#D&uUGO! z2A!XCK7nikb>CucZu10wmm8YMF&WIlAwj!J%@BR`%tw~Q`ZajXV73Wp>-=Wn!~t z3O;fb{|^Aes~~siRghrwCcbpCb5r|tL4p=+t-UhphI%Cv@`BAL*({Qx$6wUj&`F(i zG(!^tC5`etP(e}x)K3H;V^L-J;RD~|hyfx?NDm&B1LR2&YJ!s0DS(a}Dh+^Kk z!D0!#oMzkk$gvatwBOCjf|=$Eowm|*JvH6D=DXT z*>S6K#vDbSRn^Kz(Kg2`GeS(vACGpPE={2_5@7O(L!wRM3>)C(uV&g^L zPH^Ncj2>^FNLo$K>~k-P)~wF+IwyrvZ31=JlG`uM3hry9ky(VSNb)4xBVZOzJ%u&2 zBMWz9;{jQC`(4PwaO!mX|J-Zr=_d3dvHgiPcPK(?Rj_C}_TQ9BbaRyE&V4;mIFX$4 zFNg=o?C|$X(8I@HFhu(}D|&`zj8W*$G2^L+cw}*92-Ecq!3DpdgrmP}YA)+0C4CX2 z>E*5_da4X)Mq4gasF}l61~jHP^%~NIidNIREVA`zYZlPD{u61&kHuJk{XO+Gx0-A` zT+k))fh;DJ?R$8qzT~kqrFhIy3d?tFuxz9`yWF7$h+yA>v%CnM7D|K#_TpsNE`6(7 zT4xGiB3=K}0wMNKl`Y~PP@JSkGwdzv|k@E zm)F0`tb(X)!}f_yYin_OEr5MvFIIq9R+dTqm56*D@`~fru4d6@ojD3%{XgoNB?SGK zOLGl<=o6{XR*Nef7$| zPpESlS7M~6dwCtO(+$zKuvO1}2v}`Kd;XTCAN`Y|5}1~4UiiD;vh%;=@H5^`U&G!n zByR{d-zNG=kt#2CZB78KnBjir( zoR|%>emN+Ud&SEl^%eF6FH&ETDXf9iQ;Fz zE1l;j6`2=Z($5|uN%Q9L!%r?Y54+@NmCW3e%$hd`uw*eCU3(8ENXjC~Eo7E{v00+e zc;H2q0^BwU|4Ci%)6XSNUc=H}WbytkQVVXl_77Cq{yr*K1S5$wpAgZ5;2yGa?77SA z*!?e-k3D=PN4hoS@OuY6^XV_7*Ea-41ld4?qQ|gu+Ci}t;a>xB5DvXthkwW(FV|rl zJ?@R)SVJ-Y<+{N_s>W@OuXtds$ z5%6NPivNIF0Q+{o1jWPR*kK09iBOncT1idS9jcw3w;KFJi*LmfAZDI<>kbRduOFv& z85@CL<8A$%p3F;k+r$$eBe4&OZhnXQ=~d=omww7mNSAWgpMSa}-1f}anYMiVY0`yR zE`5ui9ya}5di#$Ls{d6D=`s41P%Zh3y*qR;7>QqXYB;C_(X)3<;D7i zG)yRbc_>@cQf&6!?z%u6E5O{Y8VkTki@)QkI(3nRBW9iQ#RE@2LI<*K2gAUh+!9M+ zHriso{{x$&^#O7S#evUI)waiPAs;BuOe_xHd48{2yu*Y4;@FTQ_@?3UvTPm4+q)v@ zUm=gdZAqPCu5_(W)*2B7HLbuC{lB6kZ%ozt*51A@xS)vXOw&K%7b|KO5A)sKfaS0J z&%M+@al*6YrxEEj><+ssa_=TB7Du%`~&&<7A$j_*jf|i<3wD=|#ey@7orasIZp4`9#w!V&~?63LrI0)k6CC zVK;f6TrY6*;~M{NSNZ2DZ<>j9<%be7*D#6ZZd-|!sQBO(H#c@maur)Fqd&oXahvT+ z@3=pDt*|$KxRfjo3!lDZn@@npC6fAP(Hck8%?L}QN*Vjp@!0x1MTMa1~Bl( zRI@Qvu`9-A-ol0E43SofCyakuyH@$l!dtFntVF%}5j>Zj2 z2seGeHWtoyuHc>Z3Uy>Is}f%j(Tz>Fn=Hf%f`xLcZUUS}EvD{LQ1#HGm;HA16KzMD zezFL2Pc4x`T)tUj<3`#rd{viopq=;L<;Bil$#x&s`L(4cIhiZ0IsfQ+Svt;% z-ElPMREgQ*h?8bw93MXcQqaZCm@D==j;vVhCQZ{O_e&pOU>3^9<^{00(zC_RWr8`Y3&SynH}GgN**9ejC$ zAPwJe+O9yRjmOsdrj5Z+ZeJU&?vR<|`t;LC!O;77$L=8S$-8Tm_l9@I?(r7B_zV-4 zu%YL=LN9iO#7eo;mab5HS4ixnOWj1si$1YcKe3sdS7uhLr967VdraHs9ILMtw9D5! zIAn;=>Lj$81K!4T2k8;!UpL~zyT5&kBz26&7wm7JJ&Ba=8^ofTAL6vjZw){XXD`FfrJFxwWL~T!q+VUQ#fx61n5-$&*DxnV|W7$8LfC z4upc{I=c3d!hJ@qMH|yZkeO6|(K2u0BEu+6oJAEWy$%Os6yB<>QWxh{kPcE`C zHOyuvT9%h=hRiSNV87-)e~>IcSh?4Uu1dbT_XilDS91@$a#V}Idik}!>xKKRe)vsm z28rqNx=W$i7UiAmgy-(o%9W4%P|j&KT-~l@%$*<09 zK^OkpLK&Q>H)l)h9u36vSU7N7HUpSY?~PfsRhe1N%$F}yi@qf`3+Ii}+`V2hSXW?Iz?9j1WXJR$p!1IP96%H(gaK58vpK9hvgU(`RpYN2{@xs|L*1 zb@*|hOKA8g+wmJV5x<$iY#`3dhgekQ`;udP>2X!Wx8I2D&$>5{EH|`^uuRQ|0RK!hj5R ztxD$11lNnt@XXThxay{wO4r;^8q(x!D9x#*YBSa)HKmhW{|<=$l3r!{yYyX)DB68~ zvhU7{vXqaYaig}bYMF;(jmt~em*UJrlF#exZ92;IpotThHs-NI* zRJ%@7*>Txg+)WdSRJmf! zNmvKn5ef6a;KQyX^uzi}xnN(z>LXihZXib&cyY(vf%aWK$>yKHr2nR$V!t#Cmv(XL zRy?6?6uUa?OMYZUl+4Kq_Hm`@2_3F~)Nw|QR5^mVf}f3!xwq&z^%*!8yknyjYGlx#fH)w6sXg@VFww$Ay5f+C8@dg~lz zxsp_$r5`AKYu*;4pm&Ia4=p5(rPe6^51J3LZmsP#7q_d+w~|tUqF)|>_RJrz=TKkG z=SY#>E&P3GBRj%cinZ6}ae9(n(U7;kmL<47T-g1XqN^ivDJ*s`b+VuB%RhfpHo*|% zBhFgLXY3i@iTr=stTzHCJQYIyVoiARF?;;ec!y%FG@WJ~1At}RE(pdsRAk1KioPAZ z)Xg~`9=6DnH(LRn!_NpMeg2?`1IH75QU|`Ss%J1?RymNUTo|6|hbyDudc|uuAikl2 z-}I5Lp)|qMK^ZltW8e){CIyt_+Uc?pHq$Cr5HBK}CAn8^j*VESh(X|&d>0I~QQ|gC zKQ>l6!%>~}^r$XqXb9%r@rOgz?N3|&(zBzMY9w##?yZCGkEz3lFV+KFYHox?=Z*?; zO)k1gZ4ar456o*Qy@qFzGHS}S$k~wK7XHsL{P76aiz2(rL`q-m4T-7M_&D|t)P}H% zr%BaRb}C>_{a;JQiVxcpOwJKT!!t}rhP~$D5cms)5wdt1g7XhKg`ulch~C;~Bbr$` zc28dtIZw%;{!Yu zp?xm&Xop}^DzraONVw;Xdf&rjjaFW?is6zEX1%9cM#+CYv3h=;r@DAlxWkH^?HzHB z9wi-h*NCLjYzHUWRXt=7aQyaRqyUn=E1|g=8KDfyvWEmGti@f}oMTiwzjPXH@sG5G zsL!TG+fl_fDCTfKP!2zCqSM{$4_?qbE43D23v)+>{T?K zO%JH1|8kX#-$u^U)#f130D>m;8S}o6KFLPy(M>o;;4SJk-a@Ymvyd1pVPmVES0ZBB z3FJ%{$h%oA(LhCTy}*;77ww$b(<&TChZR}zG}fUatIXY)Rk7KvUdb9_K2gz^z@ki8 z=PkSfCZy5T`LOC_R|@RC*>dk?`P}m7EWF9f5audn9hsR^}VLo9%Jn(9gSpuhjw65Fs&Uts_hFXeb02uZV{L) z9W~20_0C8=-jite2s`{2-{s8A+O7{lcvO1 zf{q}jlr6W=E%66_mq;{YudtZ--@-(pmZRTGgjL{bp50K*145!n!o-_h_E*0kyHxz9 zV;o3iQtu(>yts=brhBbpK1|P|of@~K#>spxI)5vH<^4JF>obKyt=sawK5tsyXC0LI zr6-lwxr|%23<4l{(NA~@e=s_lu*yPaPL=KXqqFIXmI4vYU-}!&%>^k8M@puL`^&WBF1k=7CqZpa`W>V*^e|*-XOx&sRqk9Pw5&Y zR2v3QJKIYScMno;w%bXv<6@@l`D6)q+nDlYv(jVh+hc6PFE_eJYtp0pazQDUfsRvxl6=y zZaXQIq3tW9A^50xobg9-<8=>@F!T1!0hm^HVBTC(WF{}0pmupEL}b7mcQ&oX1O1dT zX+OkFq#yXdS`OmI0{;j|aFjEdWG$pTGm<9UgqwYwX_B*#+`n$Z70SuG(UL!8)uF%x z-?7B2wayZ+4oke8hXIJ!Cl|7jjayDz*l%u}b6lFf#>dtE6PF?j2c?dInzzi$@%i~TiB0j?(EE{(90^4jXC;P639Dr>ElRr{!a2G_ly+@oo6Clz$iTHhg=3Uh zLC=1KR`p09=hDB4KUvewpCI3_&&J5)S)wAPHwa~F`{_z!9{@N=%sh*!JZT|19fC3)Vm zr=HZmcQ2&&Vs9CUnvrpb2isj1c3-#t`Oo_Dyk-CR#jf>}Z?00#DnDoVp)g<7+BXEgq<`ov^XwPo(n??8>hw)7F*0 z(&bky`NehE`v1CLU{L*vGLLoTFL3!Sdt!+aZ9cyY3X-pU$DWy{AZBDoniw9RmQ@@? zIQ$RGA52Zt57E)0CU(J}w|PaJd`M*NWwH z#6KRmQ!jv=K?b+~%sr#4ONn)Umr~KLuGsc(_1m|5d%oH~nf68d@*8lKUvn-_bQgO0 zZ73IY=oAkM6$0J5AIV`0&>18y7O?R5ZU@On-)okvwDPg8!ia3q z%s~j&sCORzKN{5anv>{PZ}p3%FtbZbf;AJe)Xojb_2fyIn*)bQimXL}G~5HNk+KyT zArjr-#qMTx{tz$EWe8;}3M+Yv4S=+BRH=-%$*dJQ)~x-y5{zkadM3xh`7Gxcnehkx zaWe@klVMEOVJ&A_7Y)UTHwBn5B1rl=Q~I;He{eI!ICQJB-F&j!KJuGRAL`F!*dOe5 zGa=LSM*|+@u!0TFtk>b*{ocMj3^0?9=y9V_uzF;S$gHEs4r0Mtt+$G$QuGf_y49dO z!O{F5LURobUP;Jiz7d{HP>XxT!I0&er(KJ7f^Pl{5xMP>UE6YJL76})scx~a$k-hi z%}kT|ikT{KrNXvHtb)6Q_#B?M7H~-H~-Sj=bYmK-5z6-NiYi$PnLqk`gV43xujW_wFF!etiviV zHUu)9nbEm{$*;YUt*z$E0hWKaoA+DFF8{~4o$~hX^3OqbyKdL++-lE3Nv}^@)hE3U z|A%tlz1p%A((AyK5c_6oc=tvRHYg5ub(JzdM`ra3o#WTF_JlcG|a6pEnMm&ujcvwlFDhU>t ze){sSwdsB2?jvz{j(+}~ar=F&5~-Uh<%4xTI8}V4eZ?@3JQ;GARE{D>z9xv5CStHx z!qf#LIwN9D6JNB9`G_76c%|Q%%U(n0gG~!aw~n0h?O*(w;nXS27?zWuM)SQm^KFHZ z5~L)6LJ*-Rr-w8zLC>dFDWwHp{?i@M1NLa{`4pA8?|=s{oYf)7?5H5U_#$Le{=h#>4KGR zFemuGU)>XdbaOB-`K`loN3+cQa=-5P=rDa8s+axkGjvq*1it%sHT?TFEU?xuFpi$b z@`%sLv?^VE?CjtTBy7HOq|L3a#D`KQokFoO9scKc+KJNlln|ex?6=kLUFpnnRTayv z&NfTI=VzTpyxB z&U?Z8e<@72CVx44mnk2r9C^dWp^e7;cvC%g?*4V7)*T3)v23fz+zC~|pxY7_(}al2 z>5sP5=63hr^(M*Vx)zxs50(_Hmoq{5(*LLthl0e>!6Cv7Qts~1#)5j zVV6ER6W0p5HO4xxx-53f2lOkepfYw>fp=-V{A8-YyU7N#>}8ER4MKa-5Nc)hBdABN zuUD#N?OgB7jAIp(zTb4eoeZ^L^}|+a?gO3J;aX)n-^U~ zlH;hkWs~}d{93z5wn8%$vPZynWf-~n2!punzd zK(t?Wv7+qJw~)^;kQyPIyCn6MkU*E>fOQry~#s>pU+W4%><}o_x2y$3J(3aa_Dqi$WV qX5n-+jHpIYOmw0&)(o4dhe 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[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�ziz=vA*#xx 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%0Act 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�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

>-VFh=y3Jd3H$QLzW%s|uGK*P6lSY8Rs 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�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

=;3pYaq9)e2$ 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∈Nm<(8gKVpX99{}`^X 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 z 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

)) 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

c2jT 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