diff options
| author | zy <[email protected]> | 2023-11-16 17:39:26 +0800 |
|---|---|---|
| committer | zy <[email protected]> | 2023-11-16 17:39:26 +0800 |
| commit | 67b53ae0481872acd30be0541ff679a7f41c376d (patch) | |
| tree | 207168afbf24d80b3e474ea961bfcf495270d09a /source/module/monitor_kernel.h | |
| parent | bd277b53c5da993ba13ae7363d8b917c18912fa7 (diff) | |
renew
Diffstat (limited to 'source/module/monitor_kernel.h')
| -rw-r--r-- | source/module/monitor_kernel.h | 187 |
1 files changed, 9 insertions, 178 deletions
diff --git a/source/module/monitor_kernel.h b/source/module/monitor_kernel.h index f44efef..dda9108 100644 --- a/source/module/monitor_kernel.h +++ b/source/module/monitor_kernel.h @@ -1,182 +1,13 @@ -#include <linux/hrtimer.h> -#include <linux/kprobes.h> -#include <linux/ktime.h> -#include <linux/list.h> -#include <linux/slab.h> /* for kmalloc */ -#include <linux/string.h> +#include "monitor_kallsyms.h" +#include "monitor_mem.h" +#include "monitor_timer.h" +#include "monitor_trace.h" -#include <asm/uaccess.h> -#include <linux/cdev.h> -#include <linux/highmem.h> -#include <linux/sched.h> -#include <linux/sched/loadavg.h> /* for avenrun, LOAD_* */ -#include <linux/sched/mm.h> -#include <linux/sched/signal.h> -#include <linux/stacktrace.h> /* for stack_trace_print */ +extern mm_tree mm_tree_struct; +extern struct diag_variant_buffer load_monitor_variant_buffer; -#define MAX_TIMER_NUM (128) // max timer number -#define TIMER_MAX_WATCH_NUM (32) // A timer max watch number at once time -#define MAX_NAME_LEN (15) // max name length -typedef struct { - pid_t task_id; // current process id - char name[MAX_NAME_LEN + 1]; // name - void *ptr; // virtual address - int length_byte; // byte - long long threshold; // threshold value - unsigned char unsigned_flag; // unsigned flag (true: unsigned, false: signed) - unsigned char greater_flag; // reverse flag (true: >, false: <) - unsigned long time_ns; // timer interval (ns) -} watch_arg; - -typedef struct { - pid_t task_id; // current process id - char name[MAX_NAME_LEN + 2]; // name, last char automatically add '\0' - void *kptr; // kernel address + offset - int length_byte; // byte - long long threshold; // threshold value - unsigned char unsigned_flag; // unsigned flag (true: unsigned, false: signed) - unsigned char greater_flag; // reverse flag (true: >, false: <) -} kernel_watch_arg; - -typedef struct { - unsigned long long time_ns; // hrTimer time interval (ns) - struct hrtimer hr_timer; // hrTimer - ktime_t kt; // hrTimer time - unsigned sentinel; // sentinel - kernel_watch_arg - k_watch_args[TIMER_MAX_WATCH_NUM]; // all watched kernel_watch_arg -} kernel_watch_timer; - -#define TIMER_FILLED(timer) ((timer)->sentinel >= TIMER_MAX_WATCH_NUM) -#define TIMER_EMPTY(timer) (!((timer)->time_ns | (timer)->sentinel)) -#define TIMER_NO_KWARG(timer) ((timer)->sentinel == 0) - -#define TIMER_START(timer) \ - (hrtimer_start(&timer->hr_timer, timer->kt, HRTIMER_MODE_REL)) -#define TIMER_CANCEL(timer) (hrtimer_cancel(&timer->hr_timer)) - -kernel_watch_timer kernel_wtimer_list[MAX_TIMER_NUM] = { - 0}; // all kernel_watch_timer -int kernel_wtimer_num = 0; // current kernel_watch_timer number - -EXPORT_SYMBOL(kernel_wtimer_list); // export kernel_watch_timer_list -EXPORT_SYMBOL(kernel_wtimer_num); // export kernel_watch_timer_num - -// Helper function -unsigned char w_arg2k_w_arg(void *ptr, watch_arg warg, - kernel_watch_arg *k_watch_arg); - -// for timer -kernel_watch_timer *get_timer(unsigned long long time_ns); -unsigned char timer_add_watch(kernel_watch_timer *timer, - kernel_watch_arg k_watch_arg); -unsigned char timer_del_watch_by_pid(kernel_watch_timer *timer, pid_t pid); - -// for memory access -typedef struct { - pid_t task_id; // current process id - struct page *page; - void *kaddr; - struct list_head entry; -} watch_local_memory; - -static LIST_HEAD(watch_local_memory_list); - -void free_page_list(pid_t task_id); -void free_all_page_list(void); - -// static struct page *page = NULL; -// static void *kaddr = NULL; - -void *convert_user_space_ptr(pid_t pid, unsigned long kaddr); - -// for timer -// #define US2NS (1000) // Interval in microseconds -// static struct hrtimer hr_timer; -// static ktime_t kt; - -// hrTimer -enum hrtimer_restart check_variable_cb(struct hrtimer *timer); -void start_all_hrTimer(void); -void cancel_all_hrTimer(void); - -unsigned char read_and_compare(kernel_watch_arg *k_arg); - -// for diag_kallsyms_lookup_name -unsigned long (*diag_kallsyms_lookup_name)(const char *name); -static struct kprobe kprobe_kallsyms_lookup_name = {.symbol_name = - "kallsyms_lookup_name"}; - -int fn_kallsyms_lookup_name_init(void); // init kallsyms_lookup_name - -// form -// https://github.com/alibaba/diagnose-tools/blob/8cd905a1c17f2201e460a2d607413a1303757a32/SOURCE/module/internal.h#L65 -// look for current function address, all the function with prefix "orig_" are -#define LOOKUP_SYMS(name) \ - do { \ - orig_##name = (void *)diag_kallsyms_lookup_name(#name); \ - if (!orig_##name) { \ - printk(KERN_ERR "kallsyms_lookup_name: %s\n", #name); \ - return -EINVAL; \ - } \ - } while (0) - -#define LOOKUP_SYMS_NORET(name) \ - do { \ - orig_##name = (void *)diag_kallsyms_lookup_name(#name); \ - if (!orig_##name) \ - pr_err("kallsyms_lookup_name: %s\n", #name); \ - } while (0) - -#define BACKTRACE_DEPTH 20 // max stack depth - -// LOOKUP_SYMS(stack_trace_save_tsk); -unsigned int (*orig_stack_trace_save_tsk)(struct task_struct *task, - unsigned long *store, - unsigned int size, - unsigned int skipnr); -// LOOKUP_SYMS(show_stack); -void (*orig_show_stack)(struct task_struct *task, unsigned long *sp, - const char *loglvl); - -// https://www.spinics.net/lists/kernel/msg3582022.html -// remove from 5.8.rc3,but it still work -// whether the task contributes to the load -#define __task_contributes_to_load(task) \ - ((READ_ONCE(task->__state) & TASK_UNINTERRUPTIBLE) != 0 && \ - (task->flags & PF_FROZEN) == 0 && \ - (READ_ONCE(task->__state) & TASK_NOLOAD) == 0) - -/// @brief print all task stack -/// @param -static void print_task_stack(void) { - struct task_struct *g, *p; // g: task group; p: task - unsigned long backtrace[BACKTRACE_DEPTH]; // save stack - unsigned int nr_bt; // stack depth - unsigned long long current_time; // last time - current_time = ktime_get_real(); - printk("Timestamp (ns): %lld\n", current_time); - printk("Recent Load: %lu.%02lu, %lu.%02lu, %lu.%02lu\n", // recent load - LOAD_INT(avenrun[0]), LOAD_FRAC(avenrun[0]), LOAD_INT(avenrun[1]), - LOAD_FRAC(avenrun[1]), LOAD_INT(avenrun[2]), LOAD_FRAC(avenrun[2])); - rcu_read_lock(); // lock run queue - // printk("Running task\n"); - do_each_thread(g, p) { - if (p->__state == TASK_RUNNING || __task_contributes_to_load(p) || - p->__state == TASK_IDLE) { - printk("task: %s, pid %d, state %d\n", p->comm, p->pid, - p->__state); //! todo - nr_bt = orig_stack_trace_save_tsk(p, backtrace, BACKTRACE_DEPTH, 0); - stack_trace_print(backtrace, nr_bt, 0); // print - } - } - while_each_thread(g, p); - rcu_read_unlock(); // unlock run queue -} +int monitor_init(void); +void monitor_exit(void); -unsigned char del_all_kwarg_by_pid(pid_t pid); +int start_watch_variable(watch_arg warg); void clear_watch(pid_t pid); -void clear_all_watch(void); - -// one more thing -int monitor_init(void); |
