Skip to content

Commit

Permalink
Merge pull request #911 from syxl-time/develop
Browse files Browse the repository at this point in the history
memwatcher:添加直接回收的监控指定进程和测试程序
  • Loading branch information
chenamy2017 authored Sep 23, 2024
2 parents 4589760 + b9136c1 commit 7c78092
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 26 deletions.
14 changes: 10 additions & 4 deletions eBPF_Supermarket/Memory_Subsystem/mem_watcher/mem_watcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ static const struct argp_option opts[] = {

{0, 0, 0, 0, "drsnoop:", 14},
{"drsnoop", 'b', 0, 0, "print drsnoop (直接回收追踪信息)"},
{"choose_pid", 'P', "PID", 0, "选择要检测直接回收信息的进程号"},

{0, 0, 0, 0, "oomkiller:", 15}, // 新增的 oomkiller 选项
{"oomkiller", 'o', 0, 0, "print oomkiller (内存不足时被杀死的进程信息)"},
Expand Down Expand Up @@ -520,9 +521,9 @@ int main(int argc, char **argv)
PROCESS_SKEL(skel_oomkiller, oomkiller); // 使用处理 oomkiller 的函数
}
else if (env.drsnoop)
{
PROCESS_SKEL(skel_drsnoop, drsnoop);
}
{
PROCESS_SKEL(skel_drsnoop, drsnoop);
}

return 0;
}
Expand Down Expand Up @@ -1077,7 +1078,12 @@ static int handle_event_drsnoop(void *ctx, void *data, size_t data_sz)
const struct data_t *e = data;
struct tm *tm;
char ts[32];
time_t t;
time_t t;

// 检查是否选择了特定的 PID,并且事件的 PID 是否匹配
if (env.choose_pid != 0 && e->id >> 32 != env.choose_pid) {
return 0; // 忽略不匹配的事件
}

time(&t);
tm = localtime(&t);
Expand Down
24 changes: 19 additions & 5 deletions eBPF_Supermarket/Memory_Subsystem/mem_watcher/test/Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
# 编译器和编译选项
CC = gcc
CFLAGS = -g
LDFLAGS = -pthread

# 可执行文件名
TARGET = test_mem

# 源文件
SRCS = test_mem.c

# 目标文件
OBJS = $(SRCS:.c=.o)

# 伪目标
.PHONY: all clean

all: test_mem
# 默认目标
all: $(TARGET)

test_mem: test_mem.c
$(CC) $(CFLAGS) -o test_mem test_mem.c
# 目标文件
$(TARGET): $(SRCS)
$(CC) $(LDFLAGS) -o $@ $(SRCS)

# 清理目标文件和可执行文件
clean:
rm -f test_mem
rm -f $(TARGET) $(OBJS)
103 changes: 86 additions & 17 deletions eBPF_Supermarket/Memory_Subsystem/mem_watcher/test/test_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,64 @@
#include <stdbool.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <signal.h>

#define ALLOC_SIZE_SMALL 4
#define ALLOC_SIZE_MEDIUM 64
#define ALLOC_SIZE_LARGE 1024
#define NUM_THREADS 10
#define ALLOC_SIZE (512 * 1024 * 1024)

static struct env {
bool overall_leak_test;
bool mem_leak;
bool mem_unleak;
bool mem_stress_test;
} env = {
.overall_leak_test = false,
.mem_leak = false,
.mem_unleak = false,
.mem_stress_test = false
};

const char argp_program_doc[] ="mem_watcher test.\n";
static volatile bool running = true; // 控制程序是否继续运行

const char argp_program_doc[] = "mem_watcher test.\n";

static const struct argp_option opts[] = {
{ NULL, 0, NULL, 0, "Memory Management Options:", 1 },
{ "overall-test", 'o', NULL, 0, "Perform overall memory test", 2 },
{ "detect-leak", 'l', NULL, 0, "Detect memory leaks", 3 },
{ "no-leak", 'n', NULL, 0, "No memory leaks expected", 3 },
{ "stress-test", 's', NULL, 0, "Perform memory stress test", 4 },
{ NULL, 'h', NULL, OPTION_HIDDEN, "show the full help", 0 },
{ NULL, 0, NULL, 0, NULL, 0 }
};

static error_t parse_arg(int key, char *arg, struct argp_state *state)
{
(void)arg;
switch (key) {
case 'o':
switch (key) {
case 'o':
env.overall_leak_test = true;
break;
case 'l':
case 'l':
env.mem_leak = true;
break;
case 'n':
case 'n':
env.mem_unleak = true;
break;
case 'h':
argp_state_help(state, stderr, ARGP_HELP_STD_HELP);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
case 's':
env.mem_stress_test = true;
break;
case 'h':
argp_state_help(state, stderr, ARGP_HELP_STD_HELP);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}

// 模拟一些处理,通过写入分配的内存
Expand Down Expand Up @@ -104,7 +116,7 @@ static void mem_leak_process() {
}
}

static void mem_unleak_process(){
static void mem_unleak_process() {
void *ptr = NULL;
int i = 0;

Expand Down Expand Up @@ -134,12 +146,43 @@ static void mem_unleak_process(){
}
}

int main(int argc, char **argv){
// 内存压力测试线程函数
void *memory_stress(void *arg) {
printf("Thread %ld starting memory allocation...\n", (long)arg);

// 分配指定大小的内存
char *memory_block = malloc(ALLOC_SIZE);
if (!memory_block) {
perror("Memory allocation failed");
return NULL;
}

// 用 0xFF 填充内存,模拟占用
memset(memory_block, 0xFF, ALLOC_SIZE);

// 保持分配的内存一段时间
while (running) {
sleep(10); // 继续分配并占用内存
}

// 释放内存
free(memory_block);
return NULL;
}

// 处理 SIGINT 信号(Ctrl+C)
void sigint_handler(int sig) {
(void)sig; // 忽略信号参数
running = false; // 设置标志以退出循环
printf("Received SIGINT, stopping...\n");
}

int main(int argc, char **argv) {
int err;
static const struct argp argp = {
.options = opts,
.parser = parse_arg,
.doc = argp_program_doc,
.options = opts,
.parser = parse_arg,
.doc = argp_program_doc,
};

err = argp_parse(&argp, argc, argv, 0, NULL, NULL);
Expand All @@ -160,5 +203,31 @@ int main(int argc, char **argv){
}
}

if (env.mem_stress_test) {
// 打印当前进程的进程号(PID)
pid_t pid = getpid();
printf("当前进程的进程号(PID): %d\n", pid);
printf("正在进行内存压力测试...\n");

sleep(2);

pthread_t threads[NUM_THREADS];

// 创建多个线程,每个线程分配 ALLOC_SIZE 大小的内存
for (long i = 0; i < NUM_THREADS; i++) {
if (pthread_create(&threads[i], NULL, memory_stress, (void *)i) != 0) {
perror("Failed to create thread");
return 1;
}
}

// 等待所有线程完成
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}

printf("所有线程完成\n");
}

return 0;
}

0 comments on commit 7c78092

Please sign in to comment.