trace add threshold_num

This commit is contained in:
zy
2023-11-19 20:30:48 -05:00
parent 9ad92898da
commit 504f2fb903
4 changed files with 95 additions and 58 deletions

View File

@@ -48,6 +48,9 @@ static long device_ioctl(struct file *file, unsigned int ioctl_num,
watch_arg warg;
ioctl_dump_param dump_param;
printk(KERN_INFO "variable_monitor fun: %s with ioctl_num %d\n", __FUNCTION__,
ioctl_num);
switch (ioctl_num) {
case 0:
// copy watch_arg
@@ -63,12 +66,16 @@ static long device_ioctl(struct file *file, unsigned int ioctl_num,
start_watch_variable(warg);
break;
case 1:
ret = copy_from_user(&dump_param, (void *)ioctl_param,
printk(KERN_INFO "variable_monitor 1\n");
ret = copy_from_user(&dump_param, (ioctl_dump_param *)ioctl_param,
sizeof(ioctl_dump_param));
printk(KERN_INFO "dump_param: %d %lu %p\n", *dump_param.user_ptr_len, dump_param.user_buf_len, dump_param.user_buf);
if (!ret) {
printk(KERN_INFO "ret\n");
ret = copy_to_user_variant_buffer(
&load_monitor_variant_buffer, dump_param.user_ptr_len,
dump_param.user_buf, dump_param.user_buf_len);
// printk(KERN_INFO "ret %d, %lu\n", ret, dump_param.user_buf_len);
}
printk(KERN_INFO "copy_to_user \n");

View File

@@ -208,6 +208,7 @@ enum hrtimer_restart check_variable_cb(struct hrtimer *timer) {
vm_record.id = event_id;
vm_record.et_type = 1; //! todo event type
vm_record.tv = ktime_get_real();
vm_record.threshold_num = j;
// printk("-------------------------------------\n");
// printk("-------------watch monitor-----------\n");

View File

@@ -1,15 +1,16 @@
#include "monitor_trace.h"
#include <asm/processor.h>
#include <asm/ptrace.h>
#include <asm/syscall.h> // for syscall_get_nr
#include <asm/syscall.h> // for syscall_get_nr
#include <linux/irq.h>
#include <linux/sched/mm.h> // for get_task_mm
#include <linux/rcupdate.h>
#include <linux/sched/mm.h> // for get_task_mm
#include <linux/syscalls.h>
#include <linux/tracehook.h>
#include <linux/rcupdate.h>
mm_tree mm_tree_struct;
struct diag_variant_buffer load_monitor_variant_buffer;
struct diag_variant_buffer load_monitor_variant_buffer;
typedef struct {
struct rcu_head rcu_head;
@@ -31,8 +32,7 @@ struct stack_frame_user {
};
static inline int diag_get_task_type(struct task_struct *tsk) {
if (orig_get_task_type)
return orig_get_task_type(&tsk->se);
if (orig_get_task_type) return orig_get_task_type(&tsk->se);
return 0;
}
@@ -47,8 +47,7 @@ static inline int orig_diag_cgroup_name(struct cgroup *cgrp, char *buf,
static inline mm_info *find_mm_info(mm_tree *mm_tree, struct mm_struct *mm) {
mm_info *info;
if (mm == NULL)
return NULL;
if (mm == NULL) return NULL;
info = radix_tree_lookup(&mm_tree->mm_tree, (unsigned long)mm);
return info;
}
@@ -81,8 +80,7 @@ static int copy_stack_frame(const void __user *fp,
ret = 1;
pagefault_disable();
if (__copy_from_user_inatomic(frame, fp, sizeof(*frame)))
ret = 0;
if (__copy_from_user_inatomic(frame, fp, sizeof(*frame))) ret = 0;
pagefault_enable();
return ret;
@@ -95,8 +93,7 @@ static int copy_stack_frame_remote(struct task_struct *tsk,
struct mm_struct *mm;
mm = get_task_mm(tsk);
if (!mm)
return 0;
if (!mm) return 0;
ret = orig_access_remote_vm(mm, (unsigned long)fp, frame, sizeof(*frame), 0);
mmput(mm);
@@ -127,24 +124,21 @@ static inline void save_stack_trace_user_remote(struct task_struct *tsk,
break;
}
if ((unsigned long)fp < regs->sp)
break;
if ((unsigned long)fp < regs->sp) break;
if (frame.ret_addr) {
trace->entries[trace->nr_entries++] = frame.ret_addr;
} else
break;
if (fp == frame.next_fp)
break;
if (fp == frame.next_fp) break;
fp = frame.next_fp;
count++;
/**
* 线上环境发现这里有hardlockup这里强制退出
*/
if (count >= trace->max_entries || count >= 100)
break;
if (count >= trace->max_entries || count >= 100) break;
}
}
@@ -161,22 +155,18 @@ static inline void __save_stack_trace_user(struct stack_trace *trace) {
frame.next_fp = NULL;
frame.ret_addr = 0;
if (!copy_stack_frame(fp, &frame))
break;
if ((unsigned long)fp < regs->sp)
break;
if (!copy_stack_frame(fp, &frame)) break;
if ((unsigned long)fp < regs->sp) break;
if (frame.ret_addr) {
trace->entries[trace->nr_entries++] = frame.ret_addr;
}
if (fp == frame.next_fp)
break;
if (fp == frame.next_fp) break;
fp = frame.next_fp;
count++;
/**
* 线上环境发现这里有hardlockup这里强制退出
*/
if (count >= trace->max_entries || count >= 100)
break;
if (count >= trace->max_entries || count >= 100) break;
}
}
@@ -202,7 +192,7 @@ static void diagnose_save_stack_trace_user(unsigned long *backtrace) {
}
static void diagnose_save_stack_trace_user_remote(struct task_struct *tsk,
unsigned long *backtrace) {
unsigned long *backtrace) {
struct stack_trace trace;
memset(&trace, 0, sizeof(trace));
@@ -226,52 +216,51 @@ void diag_task_brief(struct task_struct *tsk, task_detail *detail) {
struct task_struct *leader;
struct pt_regs *irq_regs;
if (!detail)
return;
if (!detail) return;
memset(detail, 0, sizeof(task_detail));
if (!tsk || tsk->exit_state == EXIT_ZOMBIE) // zombie
if (!tsk || tsk->exit_state == EXIT_ZOMBIE) // zombie
return;
leader = tsk->group_leader;
if (!leader || leader->exit_state == EXIT_ZOMBIE) {
return;
}
if (tsk != current) { // not current task
if (tsk != current) { // not current task
detail->user_mode = -1;
detail->syscallno = -1;
} else if (!tsk->mm) { // current task but kernel thread
} else if (!tsk->mm) { // current task but kernel thread
detail->user_mode = 0;
detail->syscallno = -1;
} else { // current task and user thread
irq_regs = get_irq_regs(); // get current irq regs
} else { // current task and user thread
irq_regs = get_irq_regs(); // get current irq regs
task_regs = task_pt_regs(tsk);
if ((irq_regs && user_mode(irq_regs)) ||
(task_regs && user_mode(task_regs))) {
detail->user_mode = 1; // user mode
detail->user_mode = 1; // user mode
} else {
detail->user_mode = 0; // kernel mode
detail->user_mode = 0; // kernel mode
}
if (task_regs) {
detail->syscallno = syscall_get_nr(tsk, task_regs); // get syscall no
detail->syscallno = syscall_get_nr(tsk, task_regs); // get syscall no
}
}
if (tsk->sched_class == orig_idle_sched_class) // idle task
if (tsk->sched_class == orig_idle_sched_class) // idle task
detail->sys_task = 2;
else if (!tsk->mm) // kernel thread
else if (!tsk->mm) // kernel thread
detail->sys_task = 1;
else
detail->sys_task = 0;
detail->pid = tsk->pid; // pid
detail->tgid = tsk->tgid; // tgid
detail->state = tsk->__state; // state
detail->task_type = diag_get_task_type(tsk); // task type
ns = task_active_pid_ns(tsk); // container pid
detail->pid = tsk->pid; // pid
detail->tgid = tsk->tgid; // tgid
detail->state = tsk->__state; // state
detail->task_type = diag_get_task_type(tsk); // task type
ns = task_active_pid_ns(tsk); // container pid
if (ns && ns != &init_pid_ns) {
detail->container_pid = task_pid_nr_ns(tsk, ns);
detail->container_tgid = task_tgid_nr_ns(tsk, ns);
@@ -280,12 +269,12 @@ void diag_task_brief(struct task_struct *tsk, task_detail *detail) {
detail->container_tgid = tsk->tgid;
}
strncpy(detail->comm, tsk->comm, TASK_COMM_LEN);
detail->comm[TASK_COMM_LEN - 1] = 0; // comm name
detail->comm[TASK_COMM_LEN - 1] = 0; // comm name
diag_cgroup_name(tsk, detail->cgroup_buf, CGROUP_NAME_LEN, 0);
diag_cgroup_name(tsk, detail->cgroup_cpuset, CGROUP_NAME_LEN, 1);
detail->cgroup_buf[CGROUP_NAME_LEN - 1] = 0; // cgroup name
detail->cgroup_cpuset[CGROUP_NAME_LEN - 1] = 0; // cgroup cpuset name
detail->cgroup_buf[CGROUP_NAME_LEN - 1] = 0; // cgroup name
detail->cgroup_cpuset[CGROUP_NAME_LEN - 1] = 0; // cgroup cpuset name
}
void diag_task_user_stack(struct task_struct *tsk, user_stack_detail *detail) {
@@ -293,13 +282,13 @@ void diag_task_user_stack(struct task_struct *tsk, user_stack_detail *detail) {
unsigned long sp, ip, bp;
struct task_struct *leader;
if (!detail){
if (!detail) {
printk("diag_task_user_stack 4\n");
return;
}
detail->stack[0] = 0;
if (!tsk || !tsk->mm){
if (!tsk || !tsk->mm) {
printk("diag_task_user_stack 5\n");
return;
}
@@ -349,15 +338,13 @@ void dump_proc_chains_argv(int style, struct task_struct *tsk, mm_tree *mm_tree,
detail->chains[i][0] = 0;
detail->tgid[i] = 0;
}
if (style == 0)
return;
if (style == 0) return;
if (!tsk || !tsk->mm)
return;
if (!tsk || !tsk->mm) return;
leader = tsk->group_leader;
if (!leader || !leader->mm ||
leader->exit_state == EXIT_ZOMBIE) { // leader is zombie or no mm
leader->exit_state == EXIT_ZOMBIE) { // leader is zombie or no mm
return;
}
@@ -380,8 +367,7 @@ void dump_proc_chains_argv(int style, struct task_struct *tsk, mm_tree *mm_tree,
detail->tgid[cnt] = walker->pid;
walker = rcu_dereference(walker->real_parent);
cnt++;
if (cnt >= PROCESS_CHAINS_COUNT)
break;
if (cnt >= PROCESS_CHAINS_COUNT) break;
}
rcu_read_unlock();
}
@@ -411,4 +397,42 @@ void dump_proc_chains_argv(int style, struct task_struct *tsk, mm_tree *mm_tree,
// }
// while_each_thread(g, p);
// rcu_read_unlock(); // unlock run queue
// }
// }
// void diag_printf_kern_stack(kern_stack_detail *kern_stack, int reverse) {
// int i;
// symbol sym;
// printf(" 内核态堆栈:\n");
// if (reverse) {
// for (i = BACKTRACE_DEPTH - 1; i >= 0; i--) {
// if (kern_stack->stack[i] == (size_t)-1 || kern_stack->stack[i] == 0) {
// continue;
// }
// sym.reset(kern_stack->stack[i]);
// if (g_symbol_parser.find_kernel_symbol(sym)) {
// printf("#@ 0x%lx %s ([kernel.kallsyms])\n", kern_stack->stack[i],
// sym.name.c_str());
// } else {
// printf("#@ 0x%lx %s\n", kern_stack->stack[i], "UNKNOWN");
// }
// }
// } else {
// for (i = 0; i < BACKTRACE_DEPTH; i++) {
// if (kern_stack->stack[i] == (size_t)-1 || kern_stack->stack[i] == 0) {
// break;
// }
// sym.reset(kern_stack->stack[i]);
// if (g_symbol_parser.find_kernel_symbol(sym)) {
// printf("#@ 0x%lx %s ([kernel.kallsyms])\n", kern_stack->stack[i],
// sym.name.c_str());
// } else {
// printf("#@ 0x%lx %s\n", kern_stack->stack[i], "UNKNOWN");
// }
// }
// }
// }
// void diag_printf_kern_stack(struct diag_kern_stack_detail *kern_stack) {
// diag_printf_kern_stack(kern_stack, 0);
// }

View File

@@ -25,6 +25,7 @@ typedef struct {
int et_type;
unsigned long id;
unsigned long long tv;
int threshold_num;
threshold threshold_record[TIMER_MAX_WATCH_NUM];
} variable_monitor_record;
@@ -99,6 +100,10 @@ void dump_proc_chains_argv(
int style, struct task_struct *tsk, mm_tree *mm_tree,
proc_chains_detail *detail); // get process chains argv
// print
// void diag_printf_kern_stack(kern_stack_detail *kern_stack);
// void diag_printf_kern_stack(kern_stack_detail *kern_stack, int reverse);
// orig_X
extern struct sched_class *orig_idle_sched_class;
extern int (*orig_get_task_type)(struct sched_entity *se);