Skip to content

Commit

Permalink
[fix] resolve memory issues
Browse files Browse the repository at this point in the history
  • Loading branch information
jyf111 committed Sep 30, 2023
1 parent 404d4a7 commit cf64242
Show file tree
Hide file tree
Showing 15 changed files with 126 additions and 85 deletions.
4 changes: 2 additions & 2 deletions eBPF_Supermarket/User_Function_Tracer/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ 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_compile_options(${app_stem} PUBLIC -Wall -Wextra)
target_compile_options(${app_stem} PUBLIC -Wall -Wextra -fsanitize=address -g)

target_link_options(${app_stem} PUBLIC -lstdc++ -lelf)
target_link_options(${app_stem} PUBLIC -lstdc++ -lelf -fsanitize=address)
target_link_libraries(${app_stem} PUBLIC ${app_stem}_skel)
12 changes: 10 additions & 2 deletions eBPF_Supermarket/User_Function_Tracer/src/demangle.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ static char *simplify(char *name) {
// remove function template "<...>"
for (size_t i = 0; i < len; i++) {
if (name[i] == '<') {
if (name[i + 1] == '<' && i >= 8 &&
strncmp(name + i - 8, "operator", 8) == 0) { // skip operator<<
i++;
size_t j = i + 1;
while (name[j] == ' ') ++j;
memmove(name + i + 1, name + j, len - j + 1);
len -= j - i - 1;
continue;
}
size_t j = i;
int nested = 1;
while (j + 1 < len) {
Expand All @@ -45,7 +54,6 @@ static char *simplify(char *name) {
}
memmove(name + i, name + j + 1, len - j);
len -= j - i + 1;
break;
}
}

Expand Down Expand Up @@ -96,7 +104,7 @@ static char *simplify(char *name) {
memmove(name + i, name + j + 1, len - j);
len -= j - i + 1;
// remove function return type
for (j = 0; j < i; j++) {
for (j = i; j > 0; j--) {
if (name[j] == ' ') {
if (j != 8 || strncmp(name, "operator", 8)) {
memmove(name, name + j + 1, len - j);
Expand Down
3 changes: 1 addition & 2 deletions eBPF_Supermarket/User_Function_Tracer/src/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ void elf_head_free(struct elf_head *elf) {
elf_end(elf->e);
close(elf->fd);
}
elf = NULL;
}

size_t get_entry_address(const char *filename) {
Expand Down Expand Up @@ -96,7 +95,7 @@ bool elf_rela_entry_next(struct elf_rela_entry *elf_e, struct elf_section *elf_s
}

void elf_rel_entry_begin(struct elf_rel_entry *elf_e, struct elf_section *elf_s,
Elf_Data *dyn_sym_data) {
Elf_Data *dyn_sym_data) {
elf_e->i = 0;
elf_e->nentries = elf_s->shdr.sh_size / elf_s->shdr.sh_entsize;
elf_e->rel_data = elf_getdata(elf_s->scn, NULL);
Expand Down
12 changes: 6 additions & 6 deletions eBPF_Supermarket/User_Function_Tracer/src/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,12 @@ bool elf_rela_entry_next(struct elf_rela_entry *elf_e, struct elf_section *elf_s
* @brief 保存ELF重定位条目
*/
struct elf_rel_entry {
size_t i; /**< 当前条目序号 */
size_t nentries; /**< 条目总数 */
Elf_Data *sym_data; /**< 符号数据 */
size_t i; /**< 当前条目序号 */
size_t nentries; /**< 条目总数 */
Elf_Data *sym_data; /**< 符号数据 */
Elf_Data *rel_data; /**< 重定位数据 */
GElf_Rel rel; /**< 重定位表项 */
GElf_Sym sym; /**< 符号表项 */
GElf_Rel rel; /**< 重定位表项 */
GElf_Sym sym; /**< 符号表项 */
};

/**
Expand All @@ -154,7 +154,7 @@ struct elf_rel_entry {
* @param[in] dyn_sym_data 动态符号数据
*/
void elf_rel_entry_begin(struct elf_rel_entry *elf_e, struct elf_section *elf_s,
Elf_Data *dyn_sym_data);
Elf_Data *dyn_sym_data);

/**
* @brief 移动到下一个ELF条目
Expand Down
4 changes: 2 additions & 2 deletions eBPF_Supermarket/User_Function_Tracer/src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include <stdlib.h>

struct module *module_init(char *name) {
struct module *module = malloc(sizeof(module));
struct module *module = malloc(sizeof(struct module));
module->name = name;
module->symbol_table = NULL;
return module;
Expand All @@ -30,8 +30,8 @@ struct module *module_init(char *name) {
void module_free(struct module *module) {
if (module) {
free(module->name);
symbol_table_free(module->symbol_table);
free(module);
module = NULL;
}
}

Expand Down
36 changes: 18 additions & 18 deletions eBPF_Supermarket/User_Function_Tracer/src/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,20 @@ static int symbol_addr_less(const void *lhs, const void *rhs) {
return addr1 < addr2 ? -1 : (addr1 > addr2 ? 1 : 0);
}

static void symbol_free(void *symbol) {
struct symbol *sym = symbol;
free(sym->name);
sym->name = NULL;
free(sym->libname);
sym->libname = NULL;
}

struct symbol_table *symbol_table_init(const char *module_name) {
struct elf_head elf;
if (!elf_head_init(&elf, module_name)) return NULL;

struct symbol_table *symbol_table = malloc(sizeof(struct symbol_table));
symbol_table->symbol_vec = vector_init(sizeof(struct symbol));
symbol_table->symbol_vec = vector_init(sizeof(struct symbol), symbol_free);
vector_reserve(symbol_table->symbol_vec, 16); // initial capability

struct elf_section elf_s;
Expand All @@ -63,7 +71,7 @@ struct symbol_table *symbol_table_init(const char *module_name) {
}
}

struct vector *libs = vector_init(sizeof(char *));
struct vector *libs = vector_init(sizeof(char *), NULL);
for (elf_section_begin(&elf_s, &elf); elf_section_next(&elf_s, &elf);) {
if (elf_s.shdr.sh_type == SHT_GNU_verdef) {
struct elf_verdef_entry elf_e;
Expand Down Expand Up @@ -94,7 +102,7 @@ struct symbol_table *symbol_table_init(const char *module_name) {
}
}

struct vector *poss = vector_init(sizeof(size_t));
struct vector *poss = vector_init(sizeof(size_t), NULL);
for (elf_section_begin(&elf_s, &elf); elf_section_next(&elf_s, &elf);) {
if (elf_s.shdr.sh_type == SHT_GNU_versym) {
struct elf_versym_entry elf_e;
Expand All @@ -110,7 +118,6 @@ struct symbol_table *symbol_table_init(const char *module_name) {
size_t dyn_str_idx = 0;
Elf_Data *dyn_sym_data = NULL;
struct symbol sym;
sym.has_demangled = 0;
for (elf_section_begin(&elf_s, &elf); elf_section_next(&elf_s, &elf);) {
if (elf_s.shdr.sh_type == SHT_DYNSYM) {
char *shstr = elf_strptr(elf.e, elf_s.str_idx, elf_s.shdr.sh_name);
Expand Down Expand Up @@ -152,7 +159,7 @@ struct symbol_table *symbol_table_init(const char *module_name) {
if (sym.size > 0) {
continue;
}
sym.name = strdup(elf_strptr(elf.e, dyn_str_idx, elf_e.sym.st_name));
sym.name = demangle(elf_strptr(elf.e, dyn_str_idx, elf_e.sym.st_name));
size_t pos = *((size_t *)vector_const_get(poss, elf_e.rela.r_info >> 32));
if (pos >= 2) {
sym.libname = strdup(*((const char **)(vector_const_get(libs, pos - 2))));
Expand All @@ -170,8 +177,7 @@ struct symbol_table *symbol_table_init(const char *module_name) {
struct elf_rel_entry elf_e;

int valid = 1; // TODO
for (elf_rel_entry_begin(&elf_e, &elf_s, dyn_sym_data);
elf_rel_entry_next(&elf_e, &elf_s);) {
for (elf_rel_entry_begin(&elf_e, &elf_s, dyn_sym_data); elf_rel_entry_next(&elf_e, &elf_s);) {
if (!strlen(elf_strptr(elf.e, dyn_str_idx, elf_e.sym.st_name))) {
valid = 0;
break;
Expand All @@ -188,7 +194,7 @@ struct symbol_table *symbol_table_init(const char *module_name) {
if (sym.size > 0) {
continue;
}
sym.name = strdup(elf_strptr(elf.e, dyn_str_idx, elf_e.sym.st_name));
sym.name = demangle(elf_strptr(elf.e, dyn_str_idx, elf_e.sym.st_name));
size_t pos = *((size_t *)vector_const_get(poss, elf_e.rel.r_info >> 32));
if (pos >= 2) {
sym.libname = strdup(*((const char **)(vector_const_get(libs, pos - 2))));
Expand All @@ -215,14 +221,16 @@ struct symbol_table *symbol_table_init(const char *module_name) {
sym.addr = elf_e.sym.st_value;
sym.addr = resolve_addr(sym.addr);
sym.size = elf_e.sym.st_size;
sym.name = strdup(elf_strptr(elf.e, elf_e.str_idx, elf_e.sym.st_name));
sym.name = demangle(elf_strptr(elf.e, elf_e.str_idx, elf_e.sym.st_name));
sym.libname = NULL;
vector_push_back(symbol_table->symbol_vec, &sym);
}
}
}

elf_head_free(&elf);
vector_free(libs);
vector_free(poss);

vector_sort(symbol_table->symbol_vec, symbol_addr_less);
vector_unique(symbol_table->symbol_vec, symbol_addr_less);
Expand All @@ -246,7 +254,6 @@ void symbol_table_free(struct symbol_table *symbol_table) {
if (symbol_table) {
vector_free(symbol_table->symbol_vec);
free(symbol_table);
symbol_table = NULL;
}
}

Expand All @@ -273,12 +280,5 @@ static int symbol_addr_compare(const void *lhs, const void *rhs) {

// assert symbol_table != NULL
const struct symbol *symbol_table_find(const struct symbol_table *symbol_table, size_t addr) {
struct symbol *sym = vector_binary_search(symbol_table->symbol_vec, &addr, symbol_addr_compare);
if (!sym->has_demangled) { // lazy demangle
char *mangled_name = sym->name;
sym->name = demangle(sym->name);
free(mangled_name);
sym->has_demangled = true;
}
return sym;
return vector_binary_search(symbol_table->symbol_vec, &addr, symbol_addr_compare);
}
3 changes: 1 addition & 2 deletions eBPF_Supermarket/User_Function_Tracer/src/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ struct symbol {
size_t addr; /**< relative virtual address */
size_t size; /**< symbol size */
char *name; /**< symbol name */
bool has_demangled;
const char *libname;
char *libname;
};

/**
Expand Down
3 changes: 1 addition & 2 deletions eBPF_Supermarket/User_Function_Tracer/src/thread_local.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ unsigned int thread_local_get_index(struct thread_local *thread_local, unsigned
for (unsigned int i = 0; i < MAX_THREAD_NUM; i++) {
if (!thread_local->tids[i]) {
thread_local->tids[i] = tid;
thread_local->records[i] = vector_init(sizeof(struct profile_record));
thread_local->records[i] = vector_init(sizeof(struct profile_record), NULL);
return i;
} else if (thread_local->tids[i] == tid) {
return i;
Expand Down Expand Up @@ -85,6 +85,5 @@ void thread_local_free(struct thread_local *thread_local) {
vector_free(thread_local->records[i]);
}
free(thread_local);
thread_local = NULL;
}
}
4 changes: 2 additions & 2 deletions eBPF_Supermarket/User_Function_Tracer/src/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ unsigned long long duration_str2ns(const char *duration) {
}

size_t resolve_addr(size_t addr) {
if (addr > 0x8048000) return addr - 0x8048000; // 32-bit load addr
if (addr > 0x400000) return addr - 0x400000; // 64-bit load addr
if (addr > 0x8048000) return addr - 0x8048000; // 32-bit load addr
if (addr > 0x400000) return addr - 0x400000; // 64-bit load addr
return addr;
}
2 changes: 1 addition & 1 deletion eBPF_Supermarket/User_Function_Tracer/src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#define UTRACE_UTIL_H

#include <stdbool.h>
#include <stddef.h> // for size_t
#include <stddef.h> // for size_t

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

Expand Down
35 changes: 20 additions & 15 deletions eBPF_Supermarket/User_Function_Tracer/src/utrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,18 @@ static struct bpf_link *uretprobe_attach(struct utrace_bpf *skel, pid_t pid, con
}

static const char *default_skipped_func[] = {
"c_start", "_start", "__libc_csu_init", "__libc_csu_fini", "__libc_start_main", "_dl_relocate_static_pie", "__x86.get_pc_thunk.bx",
"c_start",
"_start",
"__libc_csu_init",
"__libc_csu_fini",
"__libc_start_main",
"_dl_relocate_static_pie",
"__x86.get_pc_thunk.bx",
};

static bool skip_symbol(const struct symbol *symbol) {
// skip libcalls don't match lib_pattern
if (symbol->libname && !glob_match_ext(symbol->libname, env.lib_pattern))
return true;
if (symbol->libname && !glob_match_ext(symbol->libname, env.lib_pattern)) return true;
// skip functions don't match func_pattern
if (!glob_match_ext(symbol->name, env.func_pattern)) return true;
// skip functions match no_func_pattern
Expand All @@ -274,24 +279,26 @@ static int bpf_probe_attach(struct utrace_bpf *skel, struct vector *bpf_links, p
vmem_table = vmem_table_init(pid);
for (size_t i = 0; i < vmem_table_size(vmem_table); i++) {
const struct vmem *vmem = vmem_table_get(vmem_table, i);
if (i > 0 && vmem_table_get(vmem_table, i - 1)->module == vmem->module) continue; // duplicate
if (i > 0 && strcmp(module_get_name(vmem_table_get(vmem_table, i - 1)->module),
module_get_name(vmem->module)) == 0)
continue; // duplicate
const char *module_name = module_get_name(vmem->module);
const char *base_module_name = base_name(module_name);
// only trace libraries matching env.nest_lib_pattern
if (is_library(base_module_name) &&
!glob_match_ext(base_module_name, env.nest_lib_pattern))
if (is_library(base_module_name) && !glob_match_ext(base_module_name, env.nest_lib_pattern))
continue;
if (!module_init_symbol_table(vmem->module)) continue;
for (size_t j = 0; j < symbol_table_size(vmem->module->symbol_table); j++) {
for (size_t j = 0, addr = 0; j < symbol_table_size(vmem->module->symbol_table); j++) {
const struct symbol *sym = symbol_table_get(vmem->module->symbol_table, j);
if (!skip_symbol(sym)) {
if (sym->addr != addr && !skip_symbol(sym)) {
link = uprobe_attach(skel, pid, module_name, sym->addr);
++probe_cnt;
vector_push_back(bpf_links, &link);
link = uretprobe_attach(skel, pid, module_name, sym->addr);
vector_push_back(bpf_links, &link);
++probe_cnt;
vector_push_back(bpf_links, &link);
}
addr = sym->addr;
}
}
return probe_cnt;
Expand Down Expand Up @@ -403,7 +410,7 @@ int main(int argc, char **argv) {
if (!env.func_pattern) env.func_pattern = strdup("*"); // Trace all functions by default
if (!env.lib_pattern) env.lib_pattern = strdup("*"); // Trace all libcalls by default
if (!env.nest_lib_pattern) env.nest_lib_pattern = strdup(""); // Don't trace libraries by default
if (!env.no_func_pattern) env.no_func_pattern = strdup("");
if (!env.no_func_pattern) env.no_func_pattern = strdup("");

// Ensure root permission
if (geteuid() != 0) fail("Failed to run %s: permission denied", argv[0]);
Expand Down Expand Up @@ -440,15 +447,14 @@ int main(int argc, char **argv) {
// Maximize the number of file descriptors
if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) die("setrlimit");

bpf_links = vector_init(sizeof(struct bpf_link *));
bpf_links = vector_init(sizeof(struct bpf_link *), NULL);
// Store local states for each thread
thread_local = thread_local_init();

// Set pid and/or program
if (env.pid) {
pid = env.pid;
vmem_table = vmem_table_init(pid);
program = strdup(vmem_table_get_prog_name(vmem_table));
program = vmem_table_get_prog_name(pid);
} else {
program = resolve_full_path(env.argv[0]);
}
Expand Down Expand Up @@ -480,9 +486,8 @@ int main(int argc, char **argv) {
struct gdb *gdb = gdb_init(pid);
if (gdb_wait_for_signal(gdb) == -1) die("perror");

vmem_table = vmem_table_init(pid);
break_addr = resolve_addr(break_addr);
break_addr += vmem_table_get_prog_st_addr(vmem_table);
break_addr += vmem_table_get_prog_load_addr(pid);
DEBUG("Break address: %zx", break_addr);

if (gdb_enable_breakpoint(gdb, break_addr) == -1) die("perror");
Expand Down
Loading

0 comments on commit cf64242

Please sign in to comment.