/** * various_monitor cli 命令行工具 */ #include "ucli.h" #include "helpfun.h" #include #include #include #include // for ioctl #include static int task_info_extract(void *buf, unsigned int len, void *) { int *et_type; variable_monitor_record *vm_record; variable_monitor_task *tsk_info; variable_monitor_task_system *tsk_info_system; struct load_monitor_cpu_run *cpu_run; static int seq = 0; if (len == 0) return 0; et_type = (int *)buf; switch (*et_type) { case VARIABLE_MONITOR_RECORD_TYPE: if (len < sizeof(variable_monitor_record)) break; vm_record = (variable_monitor_record *)buf; printf("threshold exceeded, Timestamp %lld :\n", vm_record->tv); for (int i = 0; i < vm_record->threshold_over_count; i++) { printf("\t: pid: %d, name: %s, ptr: %p, threshold:%d, true_value:%d\n", vm_record->threshold_record[i].task_id, vm_record->threshold_record[i] .name, // Assuming name is a null-terminated string vm_record->threshold_record[i].ptr, vm_record->threshold_record[i].threshold, vm_record->threshold_record[i].true_value); } break; case VARIABLE_MONITOR_TASK_TYPE: if (len < sizeof(variable_monitor_task)) break; tsk_info = (variable_monitor_task *)buf; seq++; printf("##CGROUP:[%s] %d [%03d] [%s] state: %d\n", tsk_info->task.cgroup_buf, tsk_info->task.pid, seq, state_str(tsk_info->task.state).c_str(), tsk_info->task.state); printk_task_brief(&tsk_info->task); // system task no need print user stack | just in case if (tsk_info->task.sys_task == 1) { diag_printf_kern_stack(&tsk_info->kern_stack); } else { diag_printf_raw_stack(run_in_host ? tsk_info->task.tgid : tsk_info->task.container_tgid, tsk_info->task.container_tgid, tsk_info->task.comm, &tsk_info->raw_stack); diag_printf_kern_stack(&tsk_info->kern_stack); } printf("#* 0xffffffffffffff %s (UNKNOWN)\n", tsk_info->task.comm); diag_printf_proc_chains(&tsk_info->proc_chains); printf("##\n"); break; case VARIABLE_MONITOR_TASK_TYPE_SYSTEM: if (len < sizeof(variable_monitor_task_system)) break; tsk_info_system = (variable_monitor_task_system *)buf; seq++; printf("##CGROUP:[%s] %d [%03d] [%s] state: %d\n", tsk_info_system->task.cgroup_buf, tsk_info_system->task.pid, seq, state_str(tsk_info_system->task.state).c_str(), tsk_info_system->task.state); printk_task_brief(&tsk_info_system->task); // system task no need print raw_stack diag_printf_kern_stack(&tsk_info_system->kern_stack); printf("#* 0xffffffffffffff %s (UNKNOWN)\n", tsk_info_system->task.comm); diag_printf_proc_chains(&tsk_info->proc_chains); printf("##\n"); break; default: break; } return 0; } static void do_extract(char *buf, int len) { extract_variant_buffer(buf, len, task_info_extract, NULL); } static void do_dump(const char *arg) { static char variant_buf[VARIABLE_MONITOR_BUFFER_SIZE]; int len; int ret = 0; // 参数解析, 未实现/ 源码在 SOURCE/diagnose-tools/params_parse.h | // params_parse.cc // struct params_parser parse(arg); struct diag_ioctl_dump_param dump_param = { .user_ptr_len = &len, .user_buf_len = VARIABLE_MONITOR_BUFFER_SIZE, .user_buf = variant_buf, }; ret = diag_call_ioctl(IOCTL_DUMP_LOG, (long)&dump_param); if (ret == 0) { do_extract(variant_buf, len); } } static void do_dump_sa(const char *arg) { static char variant_buf[STAND_ALONE_BUFFER_SIZE]; int len; int ret = 0; struct diag_ioctl_dump_param dump_param = { .user_ptr_len = &len, .user_buf_len = STAND_ALONE_BUFFER_SIZE, .user_buf = variant_buf, }; ret = diag_call_ioctl(IOCTL_DUMP_LOG_SA, (long)&dump_param); if (ret == 0) { do_extract(variant_buf, len); } } static void do_pid(char *arg) { int pid = 0; int ret; sscanf(optarg, "%d", &pid); if (pid <= 0) { printf("arg err\n"); return; } printf("Get pid info: %d\n", pid); ret = diag_call_ioctl(IOCTL_PID, (long)&pid); if (ret) { printf("Get pid info err: %d\n", ret); } sleep(3); // after 3sec do_dump_sa(""); } static void do_tgid(char *arg) { int pid = 0; int ret; sscanf(optarg, "%d", &pid); if (pid <= 0) { printf("arg err\n"); return; } printf("Get tgid info: %d\n", pid); ret = diag_call_ioctl(IOCTL_TGID, (long)&pid); if (ret) { printf("Get tgid info err: %d\n", ret); } sleep(3); do_dump_sa(""); } int main(int argc, char *argv[]) { run_in_host = check_in_host(); printf("run_in_host: %d\n", run_in_host); for (int i = 0; i < argc; i++) { printf("argv[%d]: %s\n", i, argv[i]); } static const struct option long_options[] = { {"help", no_argument, 0, 0}, {"report", no_argument, 0, 0}, {"pid", required_argument, 0, 0}, {"tgid", required_argument, 0, 0}, {0, 0, 0, 0}}; int c; if (argc <= 1) { // do something default do_dump(optarg ? optarg : ""); return 0; } while (1) { int option_index = -1; c = getopt_long_only(argc, argv, "", long_options, &option_index); if (c == -1) { break; } // option_index = 2; switch (option_index) { case 0: // help // usage_pupil(); break; case 1: // report do_dump(optarg ? optarg : ""); break; case 2: // pid do_pid(optarg); break; case 3: // tgid do_tgid(optarg); break; default: // usage_pupil(); break; } } return 0; }