diff --git a/.github/workflows/ebpf_stack_analyser.yml b/.github/workflows/ebpf_stack_analyser.yml index d7ddecff8..ef5a99d5b 100644 --- a/.github/workflows/ebpf_stack_analyser.yml +++ b/.github/workflows/ebpf_stack_analyser.yml @@ -23,38 +23,31 @@ jobs: - name: Install native lib dependencies run: | - git submodule update --init --recursive + git submodule update --init --recursive eBPF_Supermarket/Stack_Analyser/ MagicEyes/ sudo apt install clang libelf1 libelf-dev zlib1g-dev - - name: Run app with native lib + - name: Compile test examples + run: | + cd eBPF_Supermarket/Stack_Analyser/testdir + gcc -o ./usdt_pthread -lpthread ./usdt_pthread.c + gcc -o ./uprobe_malloc ./uprobe_malloc.c + + - name: Compile and run app with native lib run: | cd eBPF_Supermarket/Stack_Analyser - make + make -j$(nproc) + sudo ./stack_analyzer on_cpu off_cpu memleak io readahead llc_stat probe "vfs_open" probe "t:sched:sched_switch" -d 5 - - gcc -o ./testdir/usdt_pthread ./testdir/usdt_pthread.c sudo ./stack_analyzer probe "u:pthread:pthread_create" -c "./testdir/usdt_pthread" -d 5 - - gcc -o ./testdir/uprobe_malloc ./testdir/uprobe_malloc.c sudo ./stack_analyzer probe "c:malloc" -c "./testdir/uprobe_malloc" -d 5 - - magic-eyes-build-and-test: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v3 - - - name: Install native lib dependencies - run: | - git submodule update --init --recursive - sudo apt install clang libelf1 libelf-dev zlib1g-dev - - name: Run app with native lib + - name: Compile and run MagicEyes app with native lib run: | mkdir -p MagicEyes/build cd MagicEyes/build cmake -DBUILD_STACK_ANALYZER=ON .. - make - sudo ./src/backend/system_diagnosis/stack_analyzer/stack_analyzer on_cpu off_cpu memleak io readahead llc_stat probe vfs_open -d 5 - sudo ./src/backend/system_diagnosis/stack_analyzer/stack_analyzer probe "p::vfs_open" probe "t:sched:sched_switch" -d 5 - sudo ./src/backend/system_diagnosis/stack_analyzer/stack_analyzer probe "c:malloc" -c "../../eBPF_Supermarket/Stack_Analyser/testdir/uprobe_malloc" -d 5 + make -j$(nproc) + + sudo ./src/backend/system_diagnosis/stack_analyzer/stack_analyzer on_cpu off_cpu memleak io readahead llc_stat probe "p::vfs_open" probe "t:sched:sched_switch" -d 5 sudo ./src/backend/system_diagnosis/stack_analyzer/stack_analyzer probe "u:pthread:pthread_create" -c "../../eBPF_Supermarket/Stack_Analyser/testdir/usdt_pthread" -d 5 + sudo ./src/backend/system_diagnosis/stack_analyzer/stack_analyzer probe "c:malloc" -c "../../eBPF_Supermarket/Stack_Analyser/testdir/uprobe_malloc" -d 5 diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/eBPFStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/eBPFStackCollector.h index def3dc8cb..292225da1 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/eBPFStackCollector.h +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/eBPFStackCollector.h @@ -79,23 +79,8 @@ class StackCollector 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; + virtual int ready(void) = 0; + virtual void finish(void) = 0; /// @brief 激活eBPF程序 /// @param 无 diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/io.h b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/io.h index 8cef7ece0..227b1bcf7 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/io.h +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/io.h @@ -40,10 +40,8 @@ class IOStackCollector : public StackCollector public: IOStackCollector(); - virtual int load(void); - virtual int attach(void); - virtual void detach(void); - virtual void unload(void); + virtual int ready(void); + virtual void finish(void); virtual void activate(bool tf); virtual const char *getName(void); }; diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/llc_stat.h b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/llc_stat.h index e801e4ea5..2a365255e 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/llc_stat.h +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/llc_stat.h @@ -51,10 +51,8 @@ class LlcStatStackCollector : public StackCollector public: LlcStatStackCollector(); - virtual int load(void); - virtual int attach(void); - virtual void detach(void); - virtual void unload(void); + virtual int ready(void); + virtual void finish(void); virtual void activate(bool tf); virtual const char *getName(void); void setScale(uint64_t period); diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/memleak.h b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/memleak.h index ef3f70e97..db7a5f774 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/memleak.h +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/memleak.h @@ -69,10 +69,8 @@ class MemleakStackCollector : public StackCollector public: MemleakStackCollector(); - virtual int load(void); - virtual int attach(void); - virtual void detach(void); - virtual void unload(void); + virtual int ready(void); + virtual void finish(void); virtual void activate(bool tf); virtual const char *getName(void); diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/off_cpu.h b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/off_cpu.h index df76f5789..d5bcc0aac 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/off_cpu.h +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/off_cpu.h @@ -32,10 +32,8 @@ class OffCPUStackCollector : public StackCollector public: OffCPUStackCollector(); - virtual int load(void); - virtual int attach(void); - virtual void detach(void); - virtual void unload(void); + virtual int ready(void); + virtual void finish(void); virtual void activate(bool tf); virtual const char *getName(void); }; diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/on_cpu.h b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/on_cpu.h index 34f66be85..26d11ed28 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/on_cpu.h +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/on_cpu.h @@ -38,10 +38,8 @@ class OnCPUStackCollector : public StackCollector public: void setScale(uint64_t freq); OnCPUStackCollector(); - virtual int load(void); - virtual int attach(void); - virtual void detach(void); - virtual void unload(void); + virtual int ready(void); + virtual void finish(void); virtual void activate(bool tf); virtual const char *getName(void); }; diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/probe.h b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/probe.h index 78776dd28..39dd4a7bb 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/probe.h +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/probe.h @@ -46,10 +46,8 @@ class ProbeStackCollector : public StackCollector public: void setScale(std::string probe); ProbeStackCollector(); - virtual int load(void); - virtual int attach(void); - virtual void detach(void); - virtual void unload(void); + virtual int ready(void); + virtual void finish(void); virtual void activate(bool tf); virtual const char *getName(void); }; diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/readahead.h b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/readahead.h index d3cd94850..41e48947e 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/readahead.h +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/readahead.h @@ -40,10 +40,8 @@ class ReadaheadStackCollector : public StackCollector public: ReadaheadStackCollector(); - virtual int load(void); - virtual int attach(void); - virtual void detach(void); - virtual void unload(void); + virtual int ready(void); + virtual void finish(void); virtual void activate(bool tf); virtual const char *getName(void); }; diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/template.h b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/template.h index f2b9aa53d..fe728eb4d 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/template.h +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/template.h @@ -38,10 +38,8 @@ class TemplateClass : public StackCollector public: TemplateClass(); - virtual int load(void); - virtual int attach(void); - virtual void detach(void); - virtual void unload(void); + virtual int ready(void); + virtual void finish(void); virtual void activate(bool tf); virtual const char *getName(void); }; diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/io.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/io.cpp index a4b34b359..910daaca6 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/io.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/io.cpp @@ -36,25 +36,16 @@ IOStackCollector::IOStackCollector() }; }; -int IOStackCollector::load(void) +int IOStackCollector::ready(void) { EBPF_LOAD_OPEN_INIT(); - return 0; -} - -int IOStackCollector::attach(void) -{ ATTACH_PROTO; return 0; } -void IOStackCollector::detach(void) +void IOStackCollector::finish(void) { DETACH_PROTO; -} - -void IOStackCollector::unload(void) -{ UNLOAD_PROTO; } @@ -63,6 +54,7 @@ void IOStackCollector::activate(bool tf) ACTIVE_SET(tf); } -const char *IOStackCollector::getName(void) { +const char *IOStackCollector::getName(void) +{ return "IOStackCollector"; } \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/llc_stat.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/llc_stat.cpp index 0c35456b1..575b14450 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/llc_stat.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/llc_stat.cpp @@ -37,18 +37,12 @@ uint64_t *LlcStatStackCollector::count_values(void *data) }; }; -int LlcStatStackCollector::load(void) +int LlcStatStackCollector::ready(void) { EBPF_LOAD_OPEN_INIT(); - return 0; -}; - -int LlcStatStackCollector::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); + err = parse_cpu_mask_file("/sys/devices/system/cpu/online", &online_mask, &num_online_cpus); CHECK_ERR_RN1(err, "Fail to get online CPU numbers"); num_cpus = libbpf_num_possible_cpus(); @@ -93,10 +87,10 @@ int LlcStatStackCollector::attach(void) rlinks[cpu] = bpf_program__attach_perf_event(skel->progs.on_cache_ref, pefd); CHECK_ERR_RN1(!rlinks[cpu], "Fail to attach bpf program"); } - return 0; -}; + return 0; +} -void LlcStatStackCollector::detach(void) +void LlcStatStackCollector::finish(void) { for (int cpu = 0; cpu < num_cpus; cpu++) { @@ -111,12 +105,8 @@ void LlcStatStackCollector::detach(void) free(rpefds); mlinks = rlinks = NULL; mpefds = rpefds = NULL; -}; - -void LlcStatStackCollector::unload(void) -{ UNLOAD_PROTO; -}; +} void LlcStatStackCollector::activate(bool tf) { diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/memleak.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/memleak.cpp index a45580133..9a9c5ae1f 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/memleak.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/memleak.cpp @@ -111,7 +111,7 @@ int MemleakStackCollector::attach_uprobes(struct memleak_bpf *skel) return 0; } -int MemleakStackCollector::load(void) +int MemleakStackCollector::ready(void) { EBPF_LOAD_OPEN_INIT( if (kstack) { @@ -122,28 +122,20 @@ int MemleakStackCollector::load(void) } else disable_kernel_tracepoints(skel); skel->rodata->wa_missing_free = wa_missing_free; skel->rodata->page_size = sysconf(_SC_PAGE_SIZE);); - return 0; -}; - -int MemleakStackCollector::attach(void) -{ if (!kstack) CHECK_ERR_RN1(attach_uprobes(skel), "failed to attach uprobes"); err = skel->attach(skel); CHECK_ERR_RN1(err, "Failed to attach BPF skeleton"); return 0; -}; +} -void MemleakStackCollector::detach(void) +void MemleakStackCollector::finish(void) { DETACH_PROTO; -}; - -void MemleakStackCollector::unload(void) -{ UNLOAD_PROTO; } + void MemleakStackCollector::activate(bool tf) { ACTIVE_SET(tf); diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/off_cpu.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/off_cpu.cpp index 0c74c58ed..1d9411b3d 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/off_cpu.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/off_cpu.cpp @@ -34,14 +34,9 @@ uint64_t *OffCPUStackCollector::count_values(void *data) }; }; -int OffCPUStackCollector::load(void) +int OffCPUStackCollector::ready(void) { EBPF_LOAD_OPEN_INIT(); - return 0; -} - -int OffCPUStackCollector::attach(void) -{ symbol sym; sym.name = "finish_task_switch"; if (!g_symbol_parser.complete_kernel_symbol(sym)) @@ -52,13 +47,9 @@ int OffCPUStackCollector::attach(void) return 0; } -void OffCPUStackCollector::detach(void) +void OffCPUStackCollector::finish(void) { DETACH_PROTO; -} - -void OffCPUStackCollector::unload(void) -{ UNLOAD_PROTO; } @@ -67,6 +58,7 @@ void OffCPUStackCollector::activate(bool tf) ACTIVE_SET(tf); } -const char *OffCPUStackCollector::getName(void) { +const char *OffCPUStackCollector::getName(void) +{ return "OffCPUStackCollector"; } \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/on_cpu.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/on_cpu.cpp index 9d6bca078..3bf90f748 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/on_cpu.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/on_cpu.cpp @@ -59,18 +59,12 @@ uint64_t *OnCPUStackCollector::count_values(void *data) }; }; -int OnCPUStackCollector::load(void) +int OnCPUStackCollector::ready(void) { EBPF_LOAD_OPEN_INIT(); - 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); + err = parse_cpu_mask_file("/sys/devices/system/cpu/online", &online_mask, &num_online_cpus); CHECK_ERR_RN1(err, "Fail to get online CPU numbers"); num_cpus = libbpf_num_possible_cpus(); @@ -103,6 +97,7 @@ int OnCPUStackCollector::attach(void) { if (attr.type != PERF_TYPE_SOFTWARE) { + HINT_ERR("Hardware perf events not exist, try to attach to software event"); attr.type = PERF_TYPE_SOFTWARE; attr.config = PERF_COUNT_SW_CPU_CLOCK; pefd = perf_event_open(&attr, tgid ? tgid : -1, cpu, -1, 0); @@ -119,35 +114,19 @@ int OnCPUStackCollector::attach(void) return 0; } -void OnCPUStackCollector::detach(void) +void OnCPUStackCollector::finish(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++) { - for (int i = 0; i < num_cpus; i++) - { - if (pefds[i] >= 0) - { - close(pefds[i]); - } - } - free(pefds); - pefds = NULL; + bpf_link__destroy(links[i]); + close(pefds[i]); } -}; - -void OnCPUStackCollector::unload(void) -{ + free(links); + free(pefds); + links = NULL; + pefds = NULL; UNLOAD_PROTO; -}; +} void OnCPUStackCollector::activate(bool tf) { diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/probe.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/probe.cpp index 8f3dc72a9..2fa9e0b67 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/probe.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/probe.cpp @@ -20,11 +20,7 @@ #include "trace_helpers.h" #include "uprobe_helpers.h" -// ========== implement virtual func ========== -bool tryf; -std::vector strList; -std::string func; -void splitStr(std::string symbol, const char split, std::vector &res) +void splitStr(const std::string &symbol, const char split, std::vector &res) { if (symbol == "") return; @@ -38,77 +34,23 @@ void splitStr(std::string symbol, const char split, std::vector &re pos = strs.find(split); } } -uint64_t *ProbeStackCollector::count_values(void *data) -{ - time_tuple *p = (time_tuple *)data; - return new uint64_t[scale_num]{ - p->lat, - p->count, - }; -}; -void ProbeStackCollector::setScale(std::string probe) +static bool try_fentry(struct probe_bpf *skel, const char *func) { - this->probe = probe; - splitStr(probe, ':', strList); - func = probe; - for (int i = 0; i < scale_num; i++) - scales[i].Type = probe + scales[i].Type; -}; - -static bool try_fentry(struct probe_bpf *skel, std::string func) -{ - long err; - - if (!fentry_can_attach(func.c_str(), NULL)) - { - return false; - } - err = bpf_program__set_attach_target(skel->progs.dummy_fentry, 0, func.c_str()); - if (err) + if (!fentry_can_attach(func, NULL) || + bpf_program__set_attach_target(skel->progs.dummy_fentry, 0, func) || + bpf_program__set_attach_target(skel->progs.dummy_fexit, 0, func)) { bpf_program__set_autoload(skel->progs.dummy_fentry, false); bpf_program__set_autoload(skel->progs.dummy_fexit, false); return false; } - err = bpf_program__set_attach_target(skel->progs.dummy_fexit, 0, func.c_str()); - if (err) + else { - bpf_program__set_autoload(skel->progs.dummy_fentry, false); - bpf_program__set_autoload(skel->progs.dummy_fexit, false); - - return false; + bpf_program__set_autoload(skel->progs.dummy_kprobe, false); + bpf_program__set_autoload(skel->progs.dummy_kretprobe, false); + return true; } - - bpf_program__set_autoload(skel->progs.dummy_kprobe, false); - bpf_program__set_autoload(skel->progs.dummy_kretprobe, false); - return true; -} - -int ProbeStackCollector::load(void) -{ - std::string str = func; - skel = skel->open(NULL); - CHECK_ERR_RN1(!skel, "Fail to open BPF skeleton"); - if (strList.size() == 3 && strList[0] == "p" && strList[1] == "") - str = strList[2]; - if (strList.size() == 1 || (strList.size() == 3 && strList[0] == "p" && strList[1] == "")){ - tryf = try_fentry(skel, str); - }else{ - bpf_program__set_autoload(skel->progs.dummy_fentry, false); - bpf_program__set_autoload(skel->progs.dummy_fexit, false); - } - skel->rodata->target_tgid = tgid; - skel->rodata->trace_user = ustack; - skel->rodata->trace_kernel = kstack; - skel->rodata->self_tgid = self_tgid; - skel->rodata->target_tgid = tgid; - skel->rodata->target_cgroupid = cgroup; - skel->rodata->freq = freq; - err = skel->load(skel); - CHECK_ERR_RN1(err, "Fail to load BPF skeleton"); - obj = skel->obj; - return 0; }; static int get_binpath(char *path, int pid) @@ -138,8 +80,9 @@ static int get_binpath(char *path, int pid) strcpy(path, line + i); fclose(f); return 0; -} -static int attach_kprobes(struct probe_bpf *skel, std::string func) +}; + +static int attach_kprobes(struct probe_bpf *skel, const std::string &func) { skel->links.dummy_kprobe = bpf_program__attach_kprobe(skel->progs.dummy_kprobe, false, func.c_str()); @@ -148,7 +91,8 @@ static int attach_kprobes(struct probe_bpf *skel, std::string func) bpf_program__attach_kprobe(skel->progs.dummy_kretprobe, true, func.c_str()); CHECK_ERR_RN1(!skel->links.dummy_kretprobe, "Fail to attach ketprobe"); return 0; -} +}; + static int attach_fentry(struct probe_bpf *skel) { skel->links.dummy_fentry = @@ -158,8 +102,9 @@ static int attach_fentry(struct probe_bpf *skel) bpf_program__attach(skel->progs.dummy_fexit); CHECK_ERR_RN1(!skel->links.dummy_fexit, "Fail to attach fexit"); return 0; -} -static int attach_uprobes(struct probe_bpf *skel, std::string probe, int pid) +}; + +static int attach_uprobes(struct probe_bpf *skel, const std::string &probe, int pid) { char *binary, *function; char bin_path[128]; @@ -186,18 +131,18 @@ static int attach_uprobes(struct probe_bpf *skel, std::string probe, int pid) bin_path, func_off); CHECK_ERR_RN1(!skel->links.dummy_kretprobe, "Fail to attach uprobe"); return 0; -} +}; -static int attach_tp(struct probe_bpf *skel, std::string tp_class, std::string func) +static int attach_tp(struct probe_bpf *skel, const std::string &tp_class, const std::string &func) { skel->links.tp_exit = bpf_program__attach_tracepoint(skel->progs.tp_exit, tp_class.c_str(), func.c_str()); CHECK_ERR_RN1(!skel->links.tp_exit, "Fail to attach tracepoint"); return 0; -} +}; -static int attach_usdt(struct probe_bpf *skel, std::string func, int pid) +static int attach_usdt(struct probe_bpf *skel, const std::string &func, int pid) { char bin_path[128]; int err = get_binpath(bin_path, pid); @@ -206,73 +151,83 @@ static int attach_usdt(struct probe_bpf *skel, std::string func, int pid) bpf_program__attach_usdt(skel->progs.usdt_exit, pid, bin_path, "libc", func.c_str(), NULL); CHECK_ERR_RN1(!skel->links.usdt_exit, "Fail to attach usdt"); return 0; -} +}; + +// ========== implement virtual func ========== -int ProbeStackCollector::attach(void) +uint64_t *ProbeStackCollector::count_values(void *data) { - // dynamic mounting - // std::vector strList; - // splitStr(probe, ':', strList); - // std::string func = probe; - int err = 0; - if (strList.size() == 3 && strList[0] == "p" && strList[1] == "") - func = strList[2]; - if (strList.size() == 1 || (strList.size() == 3 && strList[0] == "p" && strList[1] == "")) - { - if (!tryf) - { - err = attach_kprobes(skel, func); - return 0; - } - else - { + time_tuple *p = (time_tuple *)data; + return new uint64_t[scale_num]{ + p->lat, + p->count, + }; +}; + +void ProbeStackCollector::setScale(std::string probe) +{ + this->probe = probe; + for (int i = 0; i < scale_num; i++) + scales[i].Type = probe + scales[i].Type; +}; + +int ProbeStackCollector::ready(void) +{ + bool can_ftrace = true; + std::vector strList; + splitStr(probe, ':', strList); + EBPF_LOAD_OPEN_INIT( + if ((strList.size() == 3 && strList[0] == "p" && strList[1] == "") || + strList.size() == 1) + can_ftrace = try_fentry(skel, (strList.size() == 1 + ? probe + : strList[2]) + .c_str()); + else { + bpf_program__set_autoload(skel->progs.dummy_fentry, false); + bpf_program__set_autoload(skel->progs.dummy_fexit, false); + }); + + if ((strList.size() == 3 && strList[0] == "p" && strList[1] == "") || + strList.size() == 1) + if (can_ftrace) err = attach_fentry(skel); - return 0; - } - } + else + err = attach_kprobes(skel, (strList.size() == 1 + ? probe + : strList[2])); else if (strList.size() == 3 && strList[0] == "t") - { err = attach_tp(skel, strList[1], strList[2]); - } - else if (strList.size() == 2 || (strList.size() == 3 && strList[0] == "p" && strList[1] != "")) - { - if (strList.size() == 3) - func = strList[1] + ":" + strList[2]; - err = attach_uprobes(skel, func, tgid); - } + else if (strList.size() == 2 || + (strList.size() == 3 && strList[0] == "p" && strList[1] != "")) + err = attach_uprobes(skel, + strList.size() == 3 + ? strList[1] + ":" + strList[2] + : probe, + tgid); else if (strList.size() == 3 && strList[0] == "u") - { err = attach_usdt(skel, strList[2], tgid); - } else - { - printf("Type must be 'p', 't', or 'u' or too any args"); - } - + err = 1; CHECK_ERR_RN1(err, "Fail to attach"); - return 0; }; -void ProbeStackCollector::detach(void) +void ProbeStackCollector::finish(void) { DETACH_PROTO; -}; - -void ProbeStackCollector::unload(void) -{ UNLOAD_PROTO; }; void ProbeStackCollector::activate(bool tf) { ACTIVE_SET(tf); -} +}; const char *ProbeStackCollector::getName(void) { return "ProbeStackCollector"; -} +}; // ========== other implementations ========== diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/readahead.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/readahead.cpp index 3cc1ae2e5..536bd923b 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/readahead.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/readahead.cpp @@ -37,25 +37,16 @@ ReadaheadStackCollector::ReadaheadStackCollector() }; }; -int ReadaheadStackCollector::load(void) +int ReadaheadStackCollector::ready(void) { EBPF_LOAD_OPEN_INIT(); - return 0; -} - -int ReadaheadStackCollector::attach(void) -{ ATTACH_PROTO; return 0; } -void ReadaheadStackCollector::detach(void) +void ReadaheadStackCollector::finish(void) { DETACH_PROTO; -} - -void ReadaheadStackCollector::unload(void) -{ UNLOAD_PROTO; } @@ -64,6 +55,7 @@ void ReadaheadStackCollector::activate(bool tf) ACTIVE_SET(tf); } -const char *ReadaheadStackCollector::getName(void) { +const char *ReadaheadStackCollector::getName(void) +{ return "ReadaheadStackCollector"; } \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/template.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/template.cpp index ac3e42725..3228bc7e6 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/template.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/template.cpp @@ -27,26 +27,20 @@ uint64_t *TemplateClass::count_values(void *data) }; }; -int TemplateClass::load(void) +int TemplateClass::ready(void) { return 0; -}; - -int TemplateClass::attach(void) -{ - return 0; -}; - -void TemplateClass::detach(void){}; +} -void TemplateClass::unload(void){}; +void TemplateClass::finish(void) {}; void TemplateClass::activate(bool tf) { ACTIVE_SET(tf); } -const char *TemplateClass::getName(void) { +const char *TemplateClass::getName(void) +{ return "TemplateClass"; } diff --git a/eBPF_Supermarket/Stack_Analyser/src/main.cpp b/eBPF_Supermarket/Stack_Analyser/src/main.cpp index 6ab93e882..2c15e5af6 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/main.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/main.cpp @@ -124,8 +124,7 @@ void end_handle(void) { std::cout << std::string(*Item) << std::endl; } - Item->detach(); - Item->unload(); + Item->finish(); } if (MainConfig::command.length()) { @@ -317,14 +316,13 @@ int main(int argc, char *argv[]) (*Item)->freq = MainConfig::freq; (*Item)->kstack = MainConfig::trace_kernel; (*Item)->ustack = MainConfig::trace_user; - if ((*Item)->load() || (*Item)->attach()) + if ((*Item)->ready()) goto err; Item++; continue; err: fprintf(stderr, _ERED "Collector %s err.\n" _RE, (*Item)->getName()); - (*Item)->detach(); - (*Item)->unload(); + (*Item)->finish(); Item = StackCollectorList.erase(Item); } diff --git a/eBPF_Supermarket/Stack_Analyser/testdir/usdt_pthread.c b/eBPF_Supermarket/Stack_Analyser/testdir/usdt_pthread.c index 47acf0b06..6714faf65 100644 --- a/eBPF_Supermarket/Stack_Analyser/testdir/usdt_pthread.c +++ b/eBPF_Supermarket/Stack_Analyser/testdir/usdt_pthread.c @@ -6,42 +6,28 @@ #include // 线程函数 -void *thread_function(void *arg) { - while (1) { +void *thread_function(void *arg) +{ + while (1) + { // 打印当前线程的pid printf("Thread ID: %d\n", gettid()); // 等待一秒 sleep(1); } - pthread_exit(NULL); -} +}; -// 创建线程的函数 -void create_thread() { - pthread_t thread; - int rc; +int main() +{ - // 创建线程 - rc = pthread_create(&thread, NULL, thread_function, NULL); - if (rc) { - fprintf(stderr, "Error: pthread_create() failed with code %d\n", rc); + pthread_t thread; + if (pthread_create(&thread, NULL, thread_function, NULL)) + { + fprintf(stderr, "Error: pthread_create() failed\n"); exit(EXIT_FAILURE); } -} - -int main() { - // 打印主进程的pid - printf("Main process ID: %d\n", gettid()); - - // 调用函数创建线程 - create_thread(); - // 主进程死循环打印pid - while (1) { - printf("Main process ID: %d\n", getpid()); - // 等待一秒 - sleep(1); - } + thread_function(NULL); return 0; -} \ No newline at end of file +}; \ No newline at end of file