From f40406bd0d5ce26ecd0eaf1f9604538827f60bc1 Mon Sep 17 00:00:00 2001 From: Iain Date: Mon, 19 Jul 2021 22:17:46 +0800 Subject: [PATCH] add init.h and init.c; not finished; go home to continue --- main.c | 19 +++++++-- src/MonitorProcess.c | 98 ++++++++++++++++++++++---------------------- src/MonitorProcess.h | 2 + src/init.c | 81 ++++++++++++++++++++++++++++++++++-- src/init.h | 2 - src/main1.c | 64 ----------------------------- 6 files changed, 144 insertions(+), 122 deletions(-) delete mode 100644 src/main1.c diff --git a/main.c b/main.c index 729dea2..67b22c1 100644 --- a/main.c +++ b/main.c @@ -10,12 +10,25 @@ int main() { pthread_t unix_domain_server; //init - //get /data/data/dir - //get whitelist - //init Proc_List + //get /data/data/dir + //get whitelist + //init Proc_List + //init Global_Info printf("%ld",Proc_List[0].pid); init(); + //monitor Global_Info and decicde to kill some process + rc = pthread_create(&unix_domain_server, NULL, (void *)&server, NULL); + if (rc != 0) { + perror("unix_domain_server thread fail"); + } + + //monitor Proc_List + rc = pthread_create(&unix_domain_server, NULL, (void *)&server, NULL); + if (rc != 0) { + perror("unix_domain_server thread fail"); + } + //server rc = pthread_create(&unix_domain_server, NULL, (void *)&server, NULL); if (rc != 0) { diff --git a/src/MonitorProcess.c b/src/MonitorProcess.c index 9a277a5..11e4619 100644 --- a/src/MonitorProcess.c +++ b/src/MonitorProcess.c @@ -14,58 +14,58 @@ extern int Proc_List_Free_ID; extern int Proc_List_ID; -extern Proc_Info Proc_List[64]; //max monitor 64 process +extern Proc_Info Proc_List[PROCESS_NUMBER]; //update process cpu time and mem info by /proc/PID/stat //example: 1 (systemd) S 0 1 1 0 -1 4194560 16465 675919 50 519 44 100 678 258 20 0 1 0 13 44421120 1253 18446744073709551615 94869015482368 94869016924823 140724538057904 0 0 0 671173123 4096 1260 1 0 0 17 0 0 0 14 0 0 94869019025816 94869019170360 94869036843008 140724538064796 140724538064863 140724538064863 140724538064863 0 /* pid 进程ID 0 - comm task_struct结构体的进程名 - state 进程状态, 此处为S - ppid 父进程ID (父进程是指通过fork方式,通过clone并非父进程) - pgrp 进程组ID - session 进程会话组ID - tty_nr 当前进程的tty终点设备号 - tpgid 控制进程终端的前台进程号 - flags 进程标识位,定义在include/linux/sched.h中的PF - minflt 次要缺页中断的次数,即无需从磁盘加载内存页. 比如COW和匿名页 - cminfl 当前进程等待子进程的minflt - majflt 主要缺页中断的次数,需要从磁盘加载内存页. 比如map文件 - majflt 当前进程等待子进程的majflt - utime 该进程处于用户态的时间,单位jiffies 13 - stime 该进程处于内核态的时间,单位jiffies 14 - cutime 当前进程等待子进程的utime - cstime 当前进程等待子进程的utime - priority 进程优先级, 此次等于10. - nice nice值,取值范围[19, -20],此处等于-10 - num_threads 线程个数, 此处等于221 - itrealvalue 该字段已废弃,恒等于0 - starttime 自系统启动后的进程创建时间,单位jiffies - vsize 进程的虚拟内存大小,单位为bytes 22 - rss 进程独占内存,单位pages,4K 23 - rsslim rss大小上限 - start_code 该任务在虚拟地址空间的代码段的起始地址 - end_code 该任务在虚拟地址空间的代码段的结束地址。 - start_stack 该任务在虚拟地址空间的栈的结束地址。 - kstkesp esp(32 位堆栈指针) 的当前值, 与在进程的内核堆栈页得到的一致。 - kstkeip 指向将要执行的指令的指针, EIP(32 位指令指针)的当前值。 - pendingsig 待处理信号的位图,记录发送给进程的普通信号。 - block_sig 阻塞信号的位图。 - sigign 忽略的信号的位图。 - sigcatch 被俘获的信号的位图。 - wchan 如果该进程是睡眠状态,该值给出调度的调用点。 - nswap 被swapped的页数,当前没用。 - cnswap 所有子进程被swapped 的页数的和,当前没用。 - exit_signal 该进程结束时,向父进程所发送的信号。 - task_cpu 运行在哪个 CPU 上。 - task_rt_priority 实时进程的相对优先级别。 - task_policy 进程的调度策略,0=非实时进程,1=FIFO实时进程;2=RR实时进程 - blio_ticks 等待阻塞IO的时间 - gtime guest time of the task in jiffies - cgtime guest time of the task children in jiffies - start_data address above which program data+bss is placed - end_data address below which program data+bss is placed - start_brk address above which program heap can be expanded with br - */ + * comm task_struct结构体的进程名 + * state 进程状态, 此处为S + * ppid 父进程ID (父进程是指通过fork方式,通过clone并非父进程) + * pgrp 进程组ID + * session 进程会话组ID + * tty_nr 当前进程的tty终点设备号 + * tpgid 控制进程终端的前台进程号 + * flags 进程标识位,定义在include/linux/sched.h中的PF + * minflt 次要缺页中断的次数,即无需从磁盘加载内存页. 比如COW和匿名页 + * cminfl 当前进程等待子进程的minflt + * majflt 主要缺页中断的次数,需要从磁盘加载内存页. 比如map文件 + * majflt 当前进程等待子进程的majflt + * utime 该进程处于用户态的时间,单位jiffies 13 + * stime 该进程处于内核态的时间,单位jiffies 14 + * cutime 当前进程等待子进程的utime + * cstime 当前进程等待子进程的utime + * priority 进程优先级, 此次等于10. + * nice nice值,取值范围[19, -20],此处等于-10 + * num_threads 线程个数, 此处等于221 + * itrealvalue 该字段已废弃,恒等于0 + * starttime 自系统启动后的进程创建时间,单位jiffies + * vsize 进程的虚拟内存大小,单位为bytes 22 + * rss 进程独占内存,单位pages,4K 23 + * rsslim rss大小上限 + * start_code 该任务在虚拟地址空间的代码段的起始地址 + * end_code 该任务在虚拟地址空间的代码段的结束地址。 + * start_stack 该任务在虚拟地址空间的栈的结束地址。 + * kstkesp esp(32 位堆栈指针) 的当前值, 与在进程的内核堆栈页得到的一致。 + * kstkeip 指向将要执行的指令的指针, EIP(32 位指令指针)的当前值。 + * pendingsig 待处理信号的位图,记录发送给进程的普通信号。 + * block_sig 阻塞信号的位图。 + * sigign 忽略的信号的位图。 + * sigcatch 被俘获的信号的位图。 + * wchan 如果该进程是睡眠状态,该值给出调度的调用点。 + * nswap 被swapped的页数,当前没用。 + * cnswap 所有子进程被swapped 的页数的和,当前没用。 + * exit_signal 该进程结束时,向父进程所发送的信号。 + * task_cpu 运行在哪个 CPU 上。 + * task_rt_priority 实时进程的相对优先级别。 + * task_policy 进程的调度策略,0=非实时进程,1=FIFO实时进程;2=RR实时进程 + * blio_ticks 等待阻塞IO的时间 + * gtime guest time of the task in jiffies + * cgtime guest time of the task children in jiffies + * start_data address above which program data+bss is placed + * end_data address below which program data+bss is placed + * start_brk address above which program heap can be expanded with br + */ int updateProcInfo(Proc_Info *proc) { char file_path[64] = {0}; char buffer[512] = {0}; @@ -113,7 +113,7 @@ void updateProcList() { Proc_Info *proc; char file_path[64] = {0}; while (1) { - if (Proc_List_ID == 30) { + if (Proc_List_ID == PROCESS_NUMBER) { Proc_List_ID = 0; usleep(1000); } diff --git a/src/MonitorProcess.h b/src/MonitorProcess.h index 9a52c1f..df33033 100644 --- a/src/MonitorProcess.h +++ b/src/MonitorProcess.h @@ -5,6 +5,8 @@ #ifndef ATOP_MONITORPROCESS_H #define ATOP_MONITORPROCESS_H +#define PROCESS_NUMBER 64 //max monitor 64 process + //proc/PID/stat typedef struct { unsigned long utime; //user time diff --git a/src/init.c b/src/init.c index ff66ff3..10f1c94 100644 --- a/src/init.c +++ b/src/init.c @@ -3,17 +3,90 @@ // #include "init.h" +#include "MonitorProcess.h" +#include +#include // read dir +#include // regular expression +#include -int initCPUInfo() { +/* + * 结构体dirent的属性d_name里存储了app的名字 + * 由于c语言没有字符串数组,而且不知道师兄想怎么处理app名,所以我直接存储的数组元素类型是dirent* + * 通过app_list[index]->d_name就可以获取文件名 + */ +#define AOSP_APP_Path "/data/data" +#define White_List_Path "atop_whitelist.txt" + +static char Regex_Pattern[2][64] = {{"com.android.*"}, + {"com.google.*"}}; +static regex_t Regex_Compare[2]; //the Regex_Compare array size must equal to Regex_Rule array size + +int filterByRegex(char *buf) { + // variable declaration for regular expression + err_code = regexec(®, buf, 0, NULL, 0) return 0; } -int initMemInfo() { + +int filterByWhiteList(char *buf) { return 0; } +int getAppName() { + DIR *dir = NULL; + int app_index = 0; + struct dirent *read_result; + struct dirent *app_list[PROCESS_NUMBER]; + + if ((dir = opendir(AOSP_APP_Path)) == NULL) { + printf("open dir failed\n"); + return -1; + } + + while ((read_result = readdir(dir)) != NULL) { + // filter, ignore current dir + parent dir + if (filterByRegex(read_result->d_name) == 0 || + filterByWhiteList(read_result->d_name) == 0 || + strcmp(read_result->d_name, ".") == 0 || + strcmp(read_result->d_name, "..") == 0) + continue; + // d_type = 4 means it's a directory + if (read_result->d_type == 4) { + app_list[app_index] = read_result; + app_index++; + } + } + + // print apps' names + printf("we have %d apps\n", app_index); + for (int i = 0; i < app_index; i++) { + printf("app %d : %s\n", i, app_list[i]->d_name); + } + return 0; +} + +int init_regex() { + int rule_num = sizeof(Regex_Pattern); + if (sizeof(Regex_Compare) != rule_num) { + return -1; + } + + int id; + int err_code; + int compression_flags = REG_EXTENDED | REG_ICASE; + + for (id = 0; id < rule_num; id++) + if ((err_code = regcomp(&Regex_Compare[id], Regex_Pattern[id], compression_flags)) != 0) { + perror("set regular expression failed:\n"); + return -1; + } + return 0; +} int init() { - initCPUInfo(); - initMemInfo(); + if (init_regex() == -1) { + return -1; + } + return 0; } + diff --git a/src/init.h b/src/init.h index 41edb12..3665cd0 100644 --- a/src/init.h +++ b/src/init.h @@ -5,8 +5,6 @@ #ifndef ATOP_INIT_H #define ATOP_INIT_H -int initCPUInfo(); -int initMemInfo(); int init(); diff --git a/src/main1.c b/src/main1.c deleted file mode 100644 index 13d4f35..0000000 --- a/src/main1.c +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include // read dir -#include // regular expression -#include - -/* - * 结构体dirent的属性d_name里存储了app的名字 - * 由于c语言没有字符串数组,而且不知道师兄想怎么处理app名,所以我直接存储的数组元素类型是dirent* - * 通过app_list[index]->d_name就可以获取文件名 - */ - -int main() { - // variable declaration for reading directory - DIR* dir = NULL; - int app_max = 50; // c doesn't have dynamic array like "std::vector" in c++, so I set a large size for array - int app_index = 0; - struct dirent* read_result; - struct dirent* app_list[app_max]; - const char* app_path = "/home/wwd/CLionProjects/AndroidTest/data/data"; // test, should be /data/data in android - - // variable declaration for regular expression - regex_t reg; - int err_code; - int compression_flags = REG_EXTENDED | REG_ICASE; - char err_buff[256]; - char* reg_str = "com.android.*"; - - // set regular expression and handle error - if ((err_code = regcomp(®, reg_str, compression_flags)) != 0){ - printf("set regular expression failed:\n"); - regerror(err_code, ®, err_buff, sizeof(err_buff)); - fprintf(stderr, "%s\n", err_buff); - return -1; - } - - // read dir - if ((dir = opendir(app_path)) == NULL){ - printf("open dir failed\n"); - return -1; - } - - // get result using loop - while ((read_result = readdir(dir)) != NULL){ - // filter, ignore current dir + parent dir + com.android.* app - if (strcmp(read_result->d_name, ".") == 0 - || strcmp(read_result->d_name, "..") == 0 - || (err_code = regexec(®, read_result->d_name, 0, NULL, 0)) == 0) - continue; - // d_type = 4 means it's a directory - if (read_result->d_type == 4){ - app_list[app_index] = read_result; - app_index++; - } - } - - // print apps' names - printf("we have %d apps\n", app_index); - for (int i = 0; i < app_index; i++){ - printf("app %d : %s\n", i, app_list[i]->d_name); - } - - regfree(®); - return 0; -}