Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] 添加基于ebpf观测用户态函数时延项目 #480

Merged
merged 4 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/user_function_tracer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: user_function_tracer

on:
push:
branches:
- "*"
paths:
- "eBPF_Supermarket/User_Function_Tracer/**"
- ".github/workflows/user_function_tracer.yml"
pull_request:
branches:
- "*"
paths:
- "eBPF_Supermarket/User_Function_Tracer/**"
- ".github/workflows/user_function_tracer.yml"

jobs:
build-and-run-tracer:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Install dependencies
run: |
sudo apt update
sudo apt install -y clang cmake ninja-build libelf1 libelf-dev zlib1g-dev libbpf-dev linux-tools-$(uname -r) linux-cloud-tools-$(uname -r)

- name: Build and run
run: |
cd eBPF_Supermarket/User_Function_Tracer
bash tools/gen_vmlinux_h.sh > vmlinux/vmlinux.h
cmake -B build -S . -G Ninja
cmake --build build
gcc test/sleep.c -o test/sleep
sudo build/utrace test/sleep
8 changes: 8 additions & 0 deletions eBPF_Supermarket/User_Function_Tracer/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Language: Cpp
BasedOnStyle: Google
IndentWidth: 2
ColumnLimit: 100
PointerAlignment: Right
IncludeCategories: # let vmlinux.h come first
- Regex: '"vmlinux.h"'
Priority: -1000
4 changes: 4 additions & 0 deletions eBPF_Supermarket/User_Function_Tracer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
build/
vmlinux/vmlinux.h
*.out
*.data/
35 changes: 35 additions & 0 deletions eBPF_Supermarket/User_Function_Tracer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 3.16)

project(utrace
DESCRIPTION "User Function Tracer"
LANGUAGES C
)

SET(CMAKE_C_COMPILER /usr/bin/clang)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake)

set(BPFOBJECT_VMLINUX_H ${CMAKE_CURRENT_SOURCE_DIR}/vmlinux/vmlinux.h)

find_package(BpfObject REQUIRED)
find_package(LibBpf REQUIRED)

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/build)
set(CMAKE_EXE_LINKER_FLAGS "-lstdc++ -lelf")

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src)

# format target
file(GLOB
FILES_NEED_FORMAT
CONFIGURE_DEPENDS
"src/*.c"
"src/*.h"
"test/*.c"
)

add_custom_target(format
COMMAND clang-format --style=file -i ${FILES_NEED_FORMAT}
COMMENT "Running clang-format."
VERBATIM
)
6 changes: 6 additions & 0 deletions eBPF_Supermarket/User_Function_Tracer/TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- short live process
- arg parser
- input pid
- more tests
- ebpf uprobe max limit
- colorful log
11 changes: 11 additions & 0 deletions eBPF_Supermarket/User_Function_Tracer/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
SET(app utrace.bpf.c)
get_filename_component(app_stem ${app} NAME_WE)

bpf_object(${app_stem} ${app_stem}.bpf.c)
add_dependencies(${app_stem}_skel libbpf-build bpftool-build)

file(GLOB_RECURSE srcs CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.c)
list(REMOVE_ITEM srcs ${CMAKE_CURRENT_SOURCE_DIR}/${app_stem}.bpf.c ${CMAKE_CURRENT_SOURCE_DIR}/${app_stem}.c)
add_executable(${app_stem} ${app_stem}.c ${srcs})

target_link_libraries(${app_stem} ${app_stem}_skel)
23 changes: 23 additions & 0 deletions eBPF_Supermarket/User_Function_Tracer/src/demangle.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "demangle.h"

#include <stdlib.h>
#include <string.h>

#include "utrace.h"

char *demangle(const char *mangled_name) {
char *original_name;
long len = MAX_SYMBOL_LEN;
int status;

// mangled_name is not mangled C++ symbol
if (mangled_name[0] != '_' || mangled_name[1] != 'Z') return strdup(mangled_name);

__cxa_demangle(mangled_name, NULL, &len, &status);
if (status < 0) return strdup(mangled_name);

original_name = malloc(len);
__cxa_demangle(mangled_name, original_name, &len, &status);

return original_name;
}
9 changes: 9 additions & 0 deletions eBPF_Supermarket/User_Function_Tracer/src/demangle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef UTRACE_DEMANGLE_H
#define UTRACE_DEMANGLE_H

extern char *__cxa_demangle(const char *name, char *output, long *len, int *status);

// the return value needs to be freed
char *demangle(const char *mangled_name);

#endif // UTRACE_DEMANGLE_H
45 changes: 45 additions & 0 deletions eBPF_Supermarket/User_Function_Tracer/src/elf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "elf.h"

#include <assert.h>
#include <fcntl.h>
#include <unistd.h>

void elf_head_begin(struct elf_head* elf, const char* filename) {
elf->fd = open(filename, O_RDONLY);
assert(elf->fd >= 0);

assert(elf_version(EV_CURRENT) != EV_NONE);

elf->e = elf_begin(elf->fd, ELF_C_READ_MMAP, NULL);
assert(elf->e);

assert(gelf_getehdr(elf->e, &elf->ehdr));
}

void elf_head_end(struct elf_head* elf) {
elf_end(elf->e);
close(elf->fd);
}

void elf_section_begin(struct elf_section* elf_s, struct elf_head* elf) { elf_s->scn = NULL; }

int elf_section_next(struct elf_section* elf_s, struct elf_head* elf) {
elf_s->scn = elf_nextscn(elf->e, elf_s->scn);
return elf_s->scn && gelf_getshdr(elf_s->scn, &elf_s->shdr);
}

void elf_symbol_entry_begin(struct elf_entry* elf_e, struct elf_section* elf_s) {
elf_e->i = 0;
elf_e->num = elf_s->shdr.sh_size / elf_s->shdr.sh_entsize;
elf_e->data = elf_getdata(elf_s->scn, NULL);
elf_e->str_idx = elf_s->shdr.sh_link;
}

int elf_symbol_entry_next(struct elf_entry* elf_e, struct elf_section* elf_s) {
if ((elf_s->shdr.sh_type != SHT_SYMTAB && elf_s->shdr.sh_type != SHT_DYNSYM) ||
elf_e->i >= elf_e->num)
return 0;
gelf_getsym(elf_e->data, elf_e->i, &elf_e->sym);
elf_e->i++;
return 1;
}
37 changes: 37 additions & 0 deletions eBPF_Supermarket/User_Function_Tracer/src/elf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef UTRACE_ELF_H
#define UTRACE_ELF_H

#include <gelf.h>

struct elf_head {
int fd;
Elf* e;
GElf_Ehdr ehdr;
};

void elf_head_begin(struct elf_head* elf, const char* filename);

void elf_head_end(struct elf_head* elf);

struct elf_section {
Elf_Scn* scn;
GElf_Shdr shdr;
};

void elf_section_begin(struct elf_section* elf_s, struct elf_head* elf);

int elf_section_next(struct elf_section* elf_s, struct elf_head* elf);

struct elf_entry {
size_t i;
size_t num;
Elf_Data* data;
GElf_Sym sym;
size_t str_idx;
};

void elf_symbol_entry_begin(struct elf_entry* elf_e, struct elf_section* elf_s);

int elf_symbol_entry_next(struct elf_entry* elf_e, struct elf_section* elf_s);

#endif // UTRACE_ELF_H
34 changes: 34 additions & 0 deletions eBPF_Supermarket/User_Function_Tracer/src/log.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "log.h"

#include <stdio.h>

void print_char(char c, int cnt) {
while (cnt > 0) {
printf("%c", c);
--cnt;
}
}

void print_header() { printf("# DURATION TID FUNCTION\n"); }

void print_tid(int tid) { printf("[%6d]", tid); }

void print_time_unit(size_t ns) {
static char *units[] = {
"ns", "us", "ms", " s", " m", " h",
};
static size_t limit[] = {
1000, 1000, 1000, 1000, 60, 24, 0,
};

size_t t = ns, t_mod = 0;
int i = 0;
while (i < sizeof(units) / sizeof(units[0]) - 1) {
if (t < limit[i]) break;
t_mod = t % limit[i];
t = t / limit[i];
++i;
}

printf("%3zu.%03zu %s", t, t_mod, units[i]);
}
29 changes: 29 additions & 0 deletions eBPF_Supermarket/User_Function_Tracer/src/log.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef UTRACE_LOG_H
#define UTRACE_LOG_H

#include <stddef.h>

void print_char(char c, int cnt);

void print_header();

void print_tid(int tid);

void print_time_unit(size_t ns);

extern int debug;
#define DEBUG(fmt, ...) \
do { \
if (debug) { \
fprintf(stderr, "[DEBUG] "); \
fprintf(stderr, fmt, ##__VA_ARGS__); \
} \
} while (0)

#define ERROR(fmt, ...) \
do { \
fprintf(stderr, "[ERROR] "); \
fprintf(stderr, fmt, ##__VA_ARGS__); \
} while (0)

#endif // UTRACE_LOG_H
Loading