lcc/clcc/remote/include/clcc.h (131 lines of code) (raw):

#ifndef CLCC_H #define CLCC_H #include <dlfcn.h> #include <errno.h> #define PERF_MAX_STACK_DEPTH 127 struct clcc_call_stack{ unsigned long stack[PERF_MAX_STACK_DEPTH]; int depth; }; static const char * clcc_funcs[] = { "lbc_bpf_init", "lbc_bpf_exit", "lbc_bpf_get_maps_id", "lbc_set_event_cb", "lbc_event_loop", "lbc_map_lookup_elem", "lbc_map_lookup_elem_flags", "lbc_map_lookup_and_delete_elem", "lbc_map_delete_elem", "lbc_map_update_elem", "lbc_map_get_next_key", "lbc_attach_perf_event", "lbc_attach_kprobe", "lbc_attach_kretprobe", "lbc_attach_uprobe", "lbc_attach_uretprobe", "lbc_attach_tracepoint", "lbc_attach_raw_tracepoint", "lbc_attach_cgroup", "lbc_attach_netns", "lbc_attach_xdp", "lbc_get_map_types", }; struct clcc_struct{ /* * member: handle * description: so file file handle pointer, it should not be modified or accessed. */ void* handle; /* * member: status * description: reserved. */ int status; /* * member: init * description: install libbpf programme, * arg1: print level, 0~3. -1:do not print any thing. * arg2: attach, 0: do not attach, !0: attach * return: 0 if success. */ int (*init)(int log_level, int attach); /* * member: exit * description: uninstall libbpf programme, * return: None. */ void (*exit)(void); /* * member: get_maps_id * description: get map id from map name which quote in LBC_XXX(). * arg1: event: map name which quote in LBC_XXX(), eg: LBC_PERF_OUTPUT(e_out, struct data_t, 128), then arg is e_out. * return: >=0, failed when < 0 */ int (*get_maps_id)(char* event); /* * member: set_event_cb * description: set call back function for perf out event. * arg1: event id, get from get_maps_id. * arg2: callback function when event polled. * arg3: lost callback function when event polled. * return: 0 if success. */ int (*set_event_cb)(int id, void (*cb)(void *ctx, int cpu, void *data, unsigned int size), void (*lost)(void *ctx, int cpu, unsigned long long cnt)); /* * member: event_loop * description: poll perf out put event, usually used in pairs with set_event_cb function. * arg1: event id, get from get_maps_id. * arg2: timeout, unit seconds. -1 nevet timeout. * return: 0 if success. */ int (*event_loop)(int id, int timeout); /* * member: map_lookup_elem * description: lookup element by key. * arg1: event id, get from get_maps_id. * arg2: key point. * arg3: value point. * return: 0 if success. */ int (*map_lookup_elem)(int id, const void *key, void *value); /* * member: map_lookup_elem_flags * description: lookup element by key. * arg1: event id, get from get_maps_id. * arg2: key point. * arg3: value point. * return: 0 if success. */ int (*map_lookup_elem_flags)(int id, const void *key, void *value, unsigned long int); /* * member: map_lookup_and_delete_elem * description: lookup element by key then delete key. * arg1: event id, get from get_maps_id. * arg2: key point. * arg3: value point. * return: 0 if success. */ int (*map_lookup_and_delete_elem)(int id, const void *key, void *value); /* * member: map_delete_elem * description: lookup element by key then delete key. * arg1: event id, get from get_maps_id. * arg2: key point. * return: 0 if success. */ int (*map_delete_elem)(int id, const void *key); /* * member: map_update_elem * description: update element by key. * arg1: event id, get from get_maps_id. * arg2: key point. * arg3: value point. * return: 0 if success. */ int (*map_update_elem)(int id, const void *key, void *value); /* * member: map_get_next_key * description: walk keys from maps. * arg1: event id, get from get_maps_id. * arg2: key point. * arg3: next key point. * return: 0 if success. */ int (*map_get_next_key)(int id, const void *key, void *next_key); /* * member: attach_perf_event * description: attach perf event. * arg1: function name in bpf.c. * arg2: perf event id. * return: 0 if success. */ int (*attach_perf_event)(const char* func, int pfd); /* * member: attach_kprobe * description: attach kprobe. * arg1: function name in bpf.c. * arg2: kprobe symbol. * return: 0 if success. */ int (*attach_kprobe)(const char* func, const char* sym); /* * member: attach_kretprobe * description: attach kprobe. * arg1: function name in bpf.c. * arg2: kprobe symbol. * return: 0 if success. */ int (*attach_kretprobe)(const char* func, const char* sym); /* * member: attach_uprobe * description: attach uprobe. * arg1: function name in bpf.c. * arg2: task pid * arg3: binary_path. * arg4: offset. * return: 0 if success. */ int (*attach_uprobe)(const char* func, int pid, const char *binary_path, unsigned long func_offset); /* * member: attach_uretprobe * description: attach uretprobe. * arg1: function name in bpf.c. * arg2: task pid * arg3: binary_path. * arg4: offset. * return: 0 if success. */ int (*attach_uretprobe)(const char* func, int pid, const char *binary_path, unsigned long func_offset); /* * member: attach_tracepoint * description: attach kprobe. * arg1: function name in bpf.c. * arg2: tp_category. * arg3: tp_name. * return: 0 if success. */ int (*attach_tracepoint)(const char* func, const char *tp_category, const char *tp_name); /* * member: attach_raw_tracepoint * description: attach kprobe. * arg1: function name in bpf.c. * arg2: tp_name. * return: 0 if success. */ int (*attach_raw_tracepoint)(const char* func, const char *tp_name); /* * member: attach_cgroup * description: attach cgroup. * arg1: function name in bpf.c. * arg2: cgroup_fd. * return: 0 if success. */ int (*attach_cgroup)(const char* func, int cgroup_fd); /* * member: attach_netns * description: attach netns. * arg1: function name in bpf.c. * arg2: netns. * return: 0 if success. */ int (*attach_netns)(const char* func, int netns); /* * member: attach_xdp * description: attach xdp. * arg1: function name in bpf.c. * arg2: ifindex. * return: 0 if success. */ int (*attach_xdp)(const char* func, int ifindex); const char* (*get_map_types)(void); }; static inline int clcc_setup_syms(void* handle, struct clcc_struct *pclcc) { void** head = (void** )&(pclcc->init); void* func = NULL; int nums = sizeof(clcc_funcs) / sizeof(const char *); int i = 0; for (i = 0; i < nums; i ++) { func = dlsym(handle, clcc_funcs[i]); if (func == NULL) { printf("can not find %s on so.", clcc_funcs[i]); return -1; } *(head ++) = func; } return 0; } /* * function name: clcc_init * description: load an so * arg1: so path to load * return: struct clcc_struct * */ static inline struct clcc_struct* clcc_init(const char* so_path) { void *handle = NULL; struct clcc_struct *pclcc = NULL; if ((handle = dlopen(so_path, RTLD_NOW)) == NULL) { printf("dlopen - %sn", dlerror()); errno = -EPERM; goto open_failed; } pclcc = (struct clcc_struct *)malloc(sizeof(struct clcc_struct)); if (pclcc == NULL) { errno = -ENOMEM; goto malloc_failed; } pclcc->handle = handle; if (clcc_setup_syms(handle, pclcc)) { errno = -ESRCH; goto setup_failed; } return pclcc; setup_failed: free(pclcc); malloc_failed: dlclose(handle); open_failed: return NULL; } /* * function name: clcc_deinit * description: release an so * arg1: struct clcc_struct *p; setup from clcc_init function, mem will be free in this function. * return: None */ static inline void clcc_deinit(struct clcc_struct* pclcc) { void *handle = pclcc->handle; free(pclcc); dlclose(handle); } /* * function name: clcc_get_call_stack * description: get call stack from table and stack id * arg1: table id: from struct clcc_struct get_maps_id function. * arg2: stack_id: from bpf kernel bpf_get_stackid function. * arg3: pstack: struct clcc_call_stack, should be alloced at first, use in clcc_print_stack * arg4: pclcc: setup from clcc_init function * return: 0 if success. */ static inline int clcc_get_call_stack(int table_id, int stack_id, struct clcc_call_stack *pstack, struct clcc_struct *pclcc) { int i; int ret; ret = pclcc->map_lookup_elem(table_id, &stack_id, &(pstack->stack[0])); if (ret != 0) { printf("get stack id %d return %d\n", stack_id, ret); return 1; } pstack->depth = PERF_MAX_STACK_DEPTH; for (i = 0; i < PERF_MAX_STACK_DEPTH; i ++) { if (pstack->stack[i] == 0) { pstack->depth = i; break; } } return 0; } #endif