diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e300724..6f74a81d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,9 +60,33 @@ if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.\n") endif() +include(cmake/libbpf.cmake) + # install frida include(cmake/frida.cmake) +# Define a helper function +function(add_ebpf_program_target target_name source_file output_file) + # opensnoop.bpf.o + execute_process(COMMAND bash -c "uname -m | sed 's/x86_64/x86/' \ +| sed 's/arm.*/arm/' \ +| sed 's/aarch64/arm64/' \ +| sed 's/ppc64le/powerpc/' \ +| sed 's/mips.*/mips/' \ +| sed 's/riscv64/riscv/' \ +| sed 's/loongarch64/loongarch/'" + OUTPUT_VARIABLE UNAME_ARCH + COMMAND_ERROR_IS_FATAL ANY + ) + string(STRIP ${UNAME_ARCH} UNAME_ARCH_STRIPPED) + add_custom_target(${target_name} ALL + COMMAND clang -O2 -target bpf -c -g -D__TARGET_ARCH_${UNAME_ARCH_STRIPPED} -I${CMAKE_SOURCE_DIR}/third_party/vmlinux/${UNAME_ARCH_STRIPPED} -I${LIBBPF_INCLUDE_DIRS}/uapi -I${LIBBPF_INCLUDE_DIRS} ${source_file} -o ${output_file} + BYPRODUCTS ${output_file} + SOURCES ${source_file} + ) + add_dependencies(${target_name} copy_headers) +endfunction() + # ebpf-verifier option(ENABLE_EBPF_VERIFIER "Whether to enable ebpf verifier" OFF) set(CMAKE_POSITION_INDEPENDENT_CODE YES) @@ -82,6 +106,9 @@ add_subdirectory(vm) add_subdirectory(runtime) add_subdirectory(tools) +# benchmark that requires bpftime libraries +add_subdirectory(benchmark) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") install(TARGETS bpftime-agent bpftime-agent-transformer bpftime-syscall-server CONFIGURATIONS Release Debug DESTINATION ~/.bpftime) diff --git a/benchmark/.gitignore b/benchmark/.gitignore new file mode 100644 index 00000000..9daeafb9 --- /dev/null +++ b/benchmark/.gitignore @@ -0,0 +1 @@ +test diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt new file mode 100644 index 00000000..c903bc43 --- /dev/null +++ b/benchmark/CMakeLists.txt @@ -0,0 +1,16 @@ +add_executable(simple-benchmark-with-embed-ebpf-calling test_embed.c) + +add_ebpf_program_target(uprobe_prog ${CMAKE_CURRENT_SOURCE_DIR}/uprobe/uprobe.bpf.c ${CMAKE_CURRENT_BINARY_DIR}/uprobe_prog.bpf.o) +add_ebpf_program_target(uretprobe_prog ${CMAKE_CURRENT_SOURCE_DIR}/uretprobe/uretprobe.bpf.c ${CMAKE_CURRENT_BINARY_DIR}/uretprobe_prog.bpf.o) + +add_dependencies(simple-benchmark-with-embed-ebpf-calling vm-bpf uprobe_prog uretprobe_prog libbpf) +target_compile_definitions(simple-benchmark-with-embed-ebpf-calling + PRIVATE + UPROBE_PROG=${CMAKE_CURRENT_BINARY_DIR}/uprobe_prog.bpf.o + URETPROBE_PROG=${CMAKE_CURRENT_BINARY_DIR}/uretprobe_prog.bpf.o +) +target_link_libraries(simple-benchmark-with-embed-ebpf-calling vm-bpf ${LIBBPF_LIBRARIES} elf z) +target_include_directories(simple-benchmark-with-embed-ebpf-calling + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}../vm/include + ${LIBBPF_INCLUDE_DIRS}) diff --git a/benchmark/syscall/.gitignore b/benchmark/syscall/.gitignore index 3b80e015..c8876c87 100644 --- a/benchmark/syscall/.gitignore +++ b/benchmark/syscall/.gitignore @@ -10,3 +10,4 @@ bootstrap opensnoop victim dump* +syscall diff --git a/benchmark/syscall/syscall b/benchmark/syscall/syscall deleted file mode 100755 index 7139f452..00000000 Binary files a/benchmark/syscall/syscall and /dev/null differ diff --git a/benchmark/syscall/victim.cpp b/benchmark/syscall/victim.cpp index 39c1ece4..d401bdce 100644 --- a/benchmark/syscall/victim.cpp +++ b/benchmark/syscall/victim.cpp @@ -19,14 +19,15 @@ uint64_t count = 0; void sigint_handler(int signum) { double avg = ((double)total_time / (double)count) / ITER_COUNT; - std::cout << "Average time usage " << std::fixed - << std::setprecision(5) << avg << "ns, " + std::cout << "Average time usage " << std::fixed << std::setprecision(5) + << avg << "ns, " << " count " << count * ITER_COUNT << std::endl; if (signum != 0) exit(0); } -void test_syscall() { +void test_syscall() +{ int fd = open("/dev/null", O_CREAT | O_RDWR); while (count < 10) { printf("Iteration %lu\n", count); @@ -60,7 +61,7 @@ int main() return 1; } } - test_syscall(); puts("Done"); + test_syscall(); return 0; } diff --git a/benchmark/test.c b/benchmark/test.c index ff50b486..ddf34393 100644 --- a/benchmark/test.c +++ b/benchmark/test.c @@ -58,8 +58,8 @@ void do_benchmark_userspace(int iter) int main() { - putchar('\n'); + puts(""); int iter = 100 * 1000; do_benchmark_userspace(iter); return 0; -} \ No newline at end of file +} diff --git a/benchmark/test_embed.c b/benchmark/test_embed.c new file mode 100644 index 00000000..34b11166 --- /dev/null +++ b/benchmark/test_embed.c @@ -0,0 +1,189 @@ +#include "ebpf_vm.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + +#if defined(__x86_64__) || defined(_M_X64) + +struct pt_regs { + uint64_t r15; + uint64_t r14; + uint64_t r13; + uint64_t r12; + uint64_t bp; + uint64_t bx; + uint64_t r11; + uint64_t r10; + uint64_t r9; + uint64_t r8; + uint64_t ax; + uint64_t cx; + uint64_t dx; + uint64_t si; + uint64_t di; + uint64_t orig_ax; + uint64_t ip; + uint64_t cs; + uint64_t flags; + uint64_t sp; + uint64_t ss; +}; +#else +#error Only x86_64 is supported +#endif + +struct ebpf_vm *begin_vm = NULL; +struct ebpf_vm *end_vm = NULL; +// ebpf_jit_fn begin_fn = NULL, end_fn = NULL; +const char *uprobe_prog = TOSTRING(UPROBE_PROG); +const char *uretprobe_prog = TOSTRING(URETPROBE_PROG); +bool enable_ebpf = false; + +// The timespec struct holds seconds and nanoseconds +struct timespec start_time, end_time; + +void start_timer() +{ + clock_gettime(CLOCK_MONOTONIC_RAW, &start_time); +} + +void end_timer() +{ + clock_gettime(CLOCK_MONOTONIC_RAW, &end_time); +} + +__attribute_noinline__ uint64_t __benchmark_test_function3(const char *a, int b, + uint64_t c) +{ + return a[b] + c; +} + +uint64_t test_func_wrapper(const char *a, int b, uint64_t c) +{ + struct pt_regs regs; + uint64_t ret; + if (enable_ebpf) { + memset(®s, 0, sizeof(regs)); + regs.di = (uintptr_t)a; + regs.si = b; + regs.dx = c; + ebpf_exec(begin_vm, ®s, sizeof(regs), &ret); + } + uint64_t hook_func_ret = __benchmark_test_function3(a, b, c); + if (enable_ebpf) { + memset(®s, 0, sizeof(regs)); + regs.di = hook_func_ret; + ebpf_exec(end_vm, ®s, sizeof(regs), &ret); + } + return hook_func_ret; +} + +static double get_elapsed_time() +{ + long seconds = end_time.tv_sec - start_time.tv_sec; + long nanoseconds = end_time.tv_nsec - start_time.tv_nsec; + if (start_time.tv_nsec > end_time.tv_nsec) { // clock underflow + --seconds; + nanoseconds += 1000000000; + } + printf("Elapsed time: %ld.%09ld seconds\n", seconds, nanoseconds); + return seconds * 1.0 + nanoseconds / 1000000000.0; +} + +static double get_function_time(int iter) +{ + start_timer(); + // test base line + for (int i = 0; i < iter; i++) { + test_func_wrapper("hello", i % 4, i); + } + end_timer(); + double time = get_elapsed_time(); + return time; +} + +void do_benchmark_userspace(int iter) +{ + double base_line_time, after_hook_time, total_time; + + printf("a[b] + c for %d times\n", iter); + base_line_time = get_function_time(iter); + printf("avg function elapse time: %lf ns\n\n", + (base_line_time) / iter * 1000000000.0); +} + +struct ebpf_vm *create_vm_from_elf(const char *elf_file, + ebpf_jit_fn *compiled_fn) +{ + LIBBPF_OPTS(bpf_object_open_opts, open_opts); + int err; + struct ebpf_vm *vm = NULL; + struct bpf_object *obj = bpf_object__open_file(elf_file, &open_opts); + if (!obj) { + fprintf(stderr, "Failed to open elf file, errno=%d\n", errno); + return NULL; + } + struct bpf_program *prog = bpf_object__next_program(obj, NULL); + if (!prog) { + fprintf(stderr, "No program found in %s\n", elf_file); + goto out; + } + vm = ebpf_create(); + if (!vm) { + goto out; + } + char *errmsg; + err = ebpf_load(vm, bpf_program__insns(prog), + bpf_program__insn_cnt(prog) * 8, &errmsg); + if (err != 0) { + fprintf(stderr, "Failed to load program: %s\n", errmsg); + free(errmsg); + goto out; + } + if (compiled_fn) { + *compiled_fn = ebpf_compile(vm, &errmsg); + if (!*compiled_fn) { + fprintf(stderr, "Failed to compile: %s\n", errmsg); + free(errmsg); + goto err_out; + } + } + goto out; +err_out: + if (vm) { + ebpf_destroy(vm); + } + +out: + if (obj) + bpf_object__close(obj); + return vm; +} + +int main() +{ + printf("uprobe elf: %s\nuretprobe elf:%s\n", uprobe_prog, + uretprobe_prog); + enable_ebpf = true; + begin_vm = create_vm_from_elf(uprobe_prog, NULL); + assert(begin_vm); + end_vm = create_vm_from_elf(uretprobe_prog, NULL); + assert(end_vm); + int iter = 100 * 1000; + do_benchmark_userspace(iter); + ebpf_destroy(begin_vm); + ebpf_destroy(end_vm); + return 0; +} diff --git a/benchmark/uprobe/uprobe b/benchmark/uprobe/uprobe index ca324858..7cccbf31 100755 Binary files a/benchmark/uprobe/uprobe and b/benchmark/uprobe/uprobe differ diff --git a/benchmark/uretprobe/.gitignore b/benchmark/uretprobe/.gitignore index ff9a9126..29362525 100644 --- a/benchmark/uretprobe/.gitignore +++ b/benchmark/uretprobe/.gitignore @@ -5,6 +5,5 @@ package.json *.skel.yaml package.yaml ecli -uertprobe .output test diff --git a/benchmark/uretprobe/uretprobe b/benchmark/uretprobe/uretprobe index 934eba6e..4402af0a 100755 Binary files a/benchmark/uretprobe/uretprobe and b/benchmark/uretprobe/uretprobe differ diff --git a/benchmark/uretprobe/uretprobe.bpf.c b/benchmark/uretprobe/uretprobe.bpf.c index b1c8bd3a..26c81c1e 100644 --- a/benchmark/uretprobe/uretprobe.bpf.c +++ b/benchmark/uretprobe/uretprobe.bpf.c @@ -5,9 +5,9 @@ SEC("uretprobe/benchmark/test:__benchmark_test_function3") -int BPF_URETPROBE(__benchmark_test_function, const char *a, int b, uint64_t c) +int BPF_URETPROBE(__benchmark_test_function, int ret) { - return b + c; + return ret; } char LICENSE[] SEC("license") = "GPL"; diff --git a/cmake/libbpf.cmake b/cmake/libbpf.cmake new file mode 100644 index 00000000..fea7f3f7 --- /dev/null +++ b/cmake/libbpf.cmake @@ -0,0 +1,63 @@ + +# +# Setup libbpf +# +set(LIBBPF_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/libbpf/) +include(ExternalProject) +ExternalProject_Add(libbpf + PREFIX libbpf + SOURCE_DIR ${LIBBPF_DIR}/src + CONFIGURE_COMMAND "mkdir" "-p" "${CMAKE_CURRENT_BINARY_DIR}/libbpf/libbpf" + BUILD_COMMAND "INCLUDEDIR=" "LIBDIR=" "UAPIDIR=" "OBJDIR=${CMAKE_CURRENT_BINARY_DIR}/libbpf/libbpf" "DESTDIR=${CMAKE_CURRENT_BINARY_DIR}/libbpf" "make" "CFLAGS=-g -O2 -Werror -Wall -std=gnu89 -fPIC -fvisibility=hidden -DSHARED -DCUSTOM_DEFINE=1" "-j" "install" + BUILD_IN_SOURCE TRUE + INSTALL_COMMAND "" + STEP_TARGETS build + BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/libbpf/libbpf.a +) + +# Set BpfObject input parameters -- note this is usually not necessary unless +# you're in a highly vendored environment (like libbpf-bootstrap) +set(LIBBPF_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/libbpf) +set(LIBBPF_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/libbpf/libbpf.a) + +# +add_custom_target(copy_headers ALL + COMMENT "Copying headers" +) + +function(copy_header TARGET SRC_DIR TARGET_DIR) + file(GLOB_RECURSE FILES RELATIVE "${SRC_DIR}" "${SRC_DIR}/*") + message(STATUS "copying ${FILES} from ${SRC_DIR} to ${TARGET_DIR}") + + foreach(file ${FILES}) + get_filename_component(PARENT_DIR "${TARGET_DIR}/${file}" DIRECTORY) + add_custom_command( + TARGET ${TARGET} + PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${PARENT_DIR} + COMMAND ${CMAKE_COMMAND} -E copy + ${SRC_DIR}/${file} + ${TARGET_DIR}/${file} + COMMENT "Copying file ${HEADER_DIRS}/${file} to ${TARGET_DIR}/${file}" + BYPRODUCTS ${TARGET_DIR}/${file} + ) + endforeach() +endfunction() + +copy_header(copy_headers "${LIBBPF_DIR}/include/linux" "${LIBBPF_INCLUDE_DIRS}/linux") +copy_header(copy_headers "${LIBBPF_DIR}/include/uapi/linux" "${LIBBPF_INCLUDE_DIRS}/linux") + +set(HEADER_FILES relo_core.h hashmap.h nlattr.h libbpf_internal.h) + +foreach(file ${HEADER_FILES}) + add_custom_command( + TARGET copy_headers + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${LIBBPF_DIR}/src/${file} + ${LIBBPF_INCLUDE_DIRS}/bpf/${file} + COMMENT "Copying ${file}" + BYPRODUCTS ${LIBBPF_INCLUDE_DIRS}/bpf/${file} + ) +endforeach() + +add_dependencies(copy_headers libbpf) diff --git a/runtime/agent-transformer/agent-transformer.cpp b/runtime/agent-transformer/agent-transformer.cpp index f87fd60b..b9f88fb0 100644 --- a/runtime/agent-transformer/agent-transformer.cpp +++ b/runtime/agent-transformer/agent-transformer.cpp @@ -9,6 +9,7 @@ #include #include #include +#include using putchar_func = int (*)(int c); using puts_func_t = int (*)(const char *); @@ -51,9 +52,16 @@ extern "C" void bpftime_agent_main(const gchar *data, gboolean *stay_resident) // avoid duplicate init orig_fn = (putchar_func)dlsym(RTLD_NEXT, "putchar"); } - auto agent_so = getenv("AGENT_SO"); + const char *agent_so = getenv("AGENT_SO"); + if (agent_so == nullptr) { + if (std::string(data) != "") { + spdlog::info("Using agent path from frida data.."); + agent_so = data; + } + } assert(agent_so && "Please set AGENT_SO to the bpftime-agent when use this tranformer"); + spdlog::info("Using agent {}", agent_so); bpftime::setup_syscall_tracer(); spdlog::info("Loading dynamic library.."); auto next_handle = diff --git a/runtime/object/CMakeLists.txt b/runtime/object/CMakeLists.txt index f5aa178f..1e5615ea 100644 --- a/runtime/object/CMakeLists.txt +++ b/runtime/object/CMakeLists.txt @@ -3,68 +3,6 @@ add_library(bpftime-object OBJECT bpf_object.cpp ) -# -# Setup libbpf -# -set(LIBBPF_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../third_party/libbpf/) -include(ExternalProject) -ExternalProject_Add(libbpf - PREFIX libbpf - SOURCE_DIR ${LIBBPF_DIR}/src - CONFIGURE_COMMAND "mkdir" "-p" "${CMAKE_CURRENT_BINARY_DIR}/libbpf/libbpf" - BUILD_COMMAND "INCLUDEDIR=" "LIBDIR=" "UAPIDIR=" "OBJDIR=${CMAKE_CURRENT_BINARY_DIR}/libbpf/libbpf" "DESTDIR=${CMAKE_CURRENT_BINARY_DIR}/libbpf" "make" "CFLAGS=-g -O2 -Werror -Wall -std=gnu89 -fPIC -fvisibility=hidden -DSHARED -DCUSTOM_DEFINE=1" "-j" "install" - BUILD_IN_SOURCE TRUE - INSTALL_COMMAND "" - STEP_TARGETS build - BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/libbpf/libbpf.a -) - -# Set BpfObject input parameters -- note this is usually not necessary unless -# you're in a highly vendored environment (like libbpf-bootstrap) -set(LIBBPF_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/libbpf) -set(LIBBPF_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/libbpf/libbpf.a) - -# -add_custom_target(copy_headers ALL - COMMENT "Copying headers" -) - -function(copy_header TARGET SRC_DIR TARGET_DIR) - file(GLOB_RECURSE FILES RELATIVE "${SRC_DIR}" "${SRC_DIR}/*") - message(STATUS "copying ${FILES} from ${SRC_DIR} to ${TARGET_DIR}") - - foreach(file ${FILES}) - get_filename_component(PARENT_DIR "${TARGET_DIR}/${file}" DIRECTORY) - add_custom_command( - TARGET ${TARGET} - PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E make_directory ${PARENT_DIR} - COMMAND ${CMAKE_COMMAND} -E copy - ${SRC_DIR}/${file} - ${TARGET_DIR}/${file} - COMMENT "Copying file ${HEADER_DIRS}/${file} to ${TARGET_DIR}/${file}" - BYPRODUCTS ${TARGET_DIR}/${file} - ) - endforeach() -endfunction() - -copy_header(copy_headers "${LIBBPF_DIR}/include/linux" "${LIBBPF_INCLUDE_DIRS}/linux") -copy_header(copy_headers "${LIBBPF_DIR}/include/uapi/linux" "${LIBBPF_INCLUDE_DIRS}/linux") - -set(HEADER_FILES relo_core.h hashmap.h nlattr.h libbpf_internal.h) - -foreach(file ${HEADER_FILES}) - add_custom_command( - TARGET copy_headers - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${LIBBPF_DIR}/src/${file} - ${LIBBPF_INCLUDE_DIRS}/bpf/${file} - COMMENT "Copying ${file}" - BYPRODUCTS ${LIBBPF_INCLUDE_DIRS}/bpf/${file} - ) -endforeach() - -add_dependencies(copy_headers libbpf) add_dependencies(bpftime-object copy_headers) add_dependencies(bpftime-object libbpf) add_dependencies(bpftime-object spdlog::spdlog) diff --git a/runtime/src/bpf_helper.cpp b/runtime/src/bpf_helper.cpp index 7c83631c..f61255ce 100644 --- a/runtime/src/bpf_helper.cpp +++ b/runtime/src/bpf_helper.cpp @@ -29,7 +29,6 @@ uint64_t bpftime_set_retval(uint64_t retval); uint64_t bpftime_trace_printk(uint64_t fmt, uint64_t fmt_size, ...) { - spdlog::debug("TRACE PRINTK: {}", (const char *)(uintptr_t)fmt); const char *fmt_str = (const char *)fmt; va_list args; #pragma clang diagnostic push diff --git a/runtime/src/bpftime_handler.cpp b/runtime/src/bpftime_handler.cpp index d61529c8..4d98a69a 100644 --- a/runtime/src/bpftime_handler.cpp +++ b/runtime/src/bpftime_handler.cpp @@ -248,7 +248,8 @@ int bpf_attach_ctx::init_attach_ctx_from_handlers( if (event_handler.type != bpf_perf_event_handler::bpf_event_type:: PERF_TYPE_TRACEPOINT) { - function = resolve_function_addr(*this, event_handler); + function = resolve_function_addr(*this, + event_handler); if (!function) { spdlog::error( "Function not found {} {}", diff --git a/tools/cli-rs/src/main.rs b/tools/cli-rs/src/main.rs index 198195f3..73333941 100644 --- a/tools/cli-rs/src/main.rs +++ b/tools/cli-rs/src/main.rs @@ -25,9 +25,15 @@ enum SubCommand { Start { #[arg(help = "Path to the executable that will be injected with agent")] executable_path: String, + #[arg(help = "Whether to enable syscall trace", short = 's', long)] + enable_syscall_trace: bool, }, #[clap(about = "Inject bpftime-agent to a certain pid")] - Attach { pid: i32 }, + Attach { + pid: i32, + #[arg(help = "Whether to enable syscall trace", short = 's', long)] + enable_syscall_trace: bool, + }, #[cfg(feature = "support-load-bpf")] #[clap(about = "Load and attach an eBPF object into kernel")] LoadBpf { @@ -51,11 +57,15 @@ struct Args { install_location: String, } -fn inject_by_frida(pid: i32, agent: impl AsRef) -> anyhow::Result<()> { +fn inject_by_frida( + pid: i32, + agent: impl AsRef, + agent_path: impl AsRef, +) -> anyhow::Result<()> { let agent = CString::new(agent.as_ref().to_string_lossy().as_bytes()) .with_context(|| anyhow!("Invalid agent path"))?; let entry_point = CString::new("bpftime_agent_main").unwrap(); - let empty_string = CString::new("").unwrap(); + let agent_path = CString::new(agent_path.as_ref().to_str().unwrap()).unwrap(); unsafe { frida_init() }; let injector = unsafe { frida_injector_new() }; let mut err: *mut _GError = std::ptr::null_mut(); @@ -65,7 +75,7 @@ fn inject_by_frida(pid: i32, agent: impl AsRef) -> anyhow::Result<()> { pid as _, agent.as_ptr(), entry_point.as_ptr(), - empty_string.as_ptr(), + agent_path.as_ptr(), std::ptr::null_mut(), &mut err as *mut _, ) @@ -119,30 +129,62 @@ fn main() -> anyhow::Result<()> { executable_path )) .exec(); - return Err(err.into()); + Err(err.into()) } - SubCommand::Start { executable_path } => { - let so_path = install_path.join("libbpftime-agent.so"); - if !so_path.exists() { - bail!("Library not found: {:?}", so_path); + SubCommand::Start { + executable_path, + enable_syscall_trace, + } => { + let agent_path = install_path.join("libbpftime-agent.so"); + if !agent_path.exists() { + bail!("Library not found: {:?}", agent_path); + } + if enable_syscall_trace { + let transformr_path = install_path.join("libbpftime-agent-transformer.so"); + + if !transformr_path.exists() { + bail!("Library not found: {:?}", transformr_path); + } + let err = exec::Command::new("bash") + .arg("-c") + .arg(format!( + "LD_PRELOAD={} AGENT_SO={} {}", + transformr_path.to_string_lossy(), + agent_path.to_string_lossy(), + executable_path + )) + .exec(); + Err(err.into()) + } else { + let err = exec::Command::new("bash") + .arg("-c") + .arg(format!( + "LD_PRELOAD={} {}", + agent_path.to_string_lossy(), + executable_path + )) + .exec(); + Err(err.into()) } - let err = exec::Command::new("bash") - .arg("-c") - .arg(format!( - "LD_PRELOAD={} {}", - so_path.to_string_lossy(), - executable_path - )) - .exec(); - return Err(err.into()); } - SubCommand::Attach { pid } => { - let so_path = install_path.join("libbpftime-agent.so"); - if !so_path.exists() { - bail!("Library not found: {:?}", so_path); + SubCommand::Attach { + pid, + enable_syscall_trace, + } => { + let agent_path = install_path.join("libbpftime-agent.so"); + if !agent_path.exists() { + bail!("Library not found: {:?}", agent_path); + } + if enable_syscall_trace { + let transformr_path = install_path.join("libbpftime-agent-transformer.so"); + + if !transformr_path.exists() { + bail!("Library not found: {:?}", transformr_path); + } + inject_by_frida(pid, transformr_path, agent_path) + } else { + inject_by_frida(pid, agent_path, "") } - println!("Inject: {:?}", so_path); - inject_by_frida(pid, so_path) } #[cfg(feature = "support-load-bpf")] SubCommand::LoadBpf { path } => load_ebpf_object_into_kernel(PathBuf::from(path)) diff --git a/tools/cli/CMakeLists.txt b/tools/cli/CMakeLists.txt index 4ee69d07..05145cac 100644 --- a/tools/cli/CMakeLists.txt +++ b/tools/cli/CMakeLists.txt @@ -26,4 +26,4 @@ target_link_libraries(bpftime Boost::program_options ) -install(TARGETS bpftime CONFIGURATIONS Release Debug DESTINATION ~/.bpftime) +# install(TARGETS bpftime CONFIGURATIONS Release Debug DESTINATION ~/.bpftime)