Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the latest code comments #602

Merged
merged 1 commit into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 30 additions & 16 deletions eBPF_Supermarket/Stack_Analyser/libbpf/bpf/io_count.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
#include "stack_analyzer.h"
#include "task.h"


//定义的哈希表以及堆栈跟踪对象
BPF_HASH(psid_count, psid, u64);
BPF_STACK_TRACE(stack_trace);
BPF_STACK_TRACE(stack_trace); //记录了相应的函数内核栈以及用户栈的使用次数
BPF_HASH(pid_tgid, u32, u32);
BPF_HASH(pid_comm, u32, comm);

Expand All @@ -39,50 +41,52 @@ static int do_stack(struct trace_event_raw_sys_enter *ctx)
{
// u64 td = bpf_get_current_pid_tgid();
// u32 pid = td >> 32;
struct task_struct* curr = (struct task_struct*)bpf_get_current_task();
u32 pid = get_task_ns_pid(curr);

struct task_struct* curr = (struct task_struct*)bpf_get_current_task();//利用bpf_get_current_task()获得当前的进程tsk
u32 pid = get_task_ns_pid(curr); //利用帮助函数获得当前进程的pid

if ((apid >= 0 && pid != apid) || !pid)
return 0;

u64 len = (u64)BPF_CORE_READ(ctx, args[3]);
u64 len = (u64)BPF_CORE_READ(ctx, args[3]); //从当前ctx中读取64位的值,并保存在len中,
if (len <= min || len > max)
return 0;

// u32 tgid = td;
u32 tgid = get_task_ns_tgid(curr);
bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY);
comm *p = bpf_map_lookup_elem(&pid_comm, &pid);
if (!p)
u32 tgid = get_task_ns_tgid(curr); //利用帮助函数获取进程的tgid
bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); //将pid_tgid表中的pid选项更新为tgid,若没有该表项,则创建
comm *p = bpf_map_lookup_elem(&pid_comm, &pid); //p指向pid_comm哈希表中的pid表项对应的value
if (!p) //如果p不为空,获取当前进程名保存至name中,如果pid_comm当中不存在pid name项,则更新
{
comm name;
bpf_get_current_comm(&name, COMM_LEN);
bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST);
}
psid apsid = {
.pid = pid,
.usid = u ? USER_STACK : -1,
.ksid = k ? KERNEL_STACK : -1,
.usid = u ? USER_STACK : -1, //u存在,则USER_STACK
.ksid = k ? KERNEL_STACK : -1, //K存在,则KERNEL_STACK
};

// record time delta
u64 *count = bpf_map_lookup_elem(&psid_count, &apsid);
u64 *count = bpf_map_lookup_elem(&psid_count, &apsid); //count指向psid_count表当中的apsid表项,即size
if (cot)
{
if (count)
if (count) //如果count不为NULL,则对count指向的值+1
(*count)++;
else
{
u64 one = 1;
u64 one = 1; //当psid_count中不存在apsid,就更新表项中的apsid=1
bpf_map_update_elem(&psid_count, &apsid, &one, BPF_NOEXIST);
}
}
else
else //cot=false
{
if (count)
if (count) //如果count不为NULL,则对count指向的值+len
(*count) += len;
else
bpf_map_update_elem(&psid_count, &apsid, &len, BPF_NOEXIST);

bpf_map_update_elem(&psid_count, &apsid, &len, BPF_NOEXIST); //当psid_count中不存在apsid,就更新表项中的apsid=len
}
return 0;
}
Expand All @@ -95,6 +99,16 @@ static int do_stack(struct trace_event_raw_sys_enter *ctx)
// tracepoint:syscalls:sys_enter_poll
// tracepoint:syscalls:sys_enter_epoll_wait


// 1. 设置挂载点
// tracepoint/syscalls/sys_enter_write 读操作
// tracepoint/syscalls/sys_enter_read 写操作
// tracepoint/syscalls/sys_enter_recvfrom 接收数据
// tracepoint/syscalls/sys_enter_sendto 发送数据

//2. 执行程序 int prog_t_##name(struct trace_event_raw_sys_enter *ctx) { return do_stack(ctx); }
//最终调用上面的do_stack函数

io_sec_tp(write);
io_sec_tp(read);
io_sec_tp(recvfrom);
Expand Down
117 changes: 68 additions & 49 deletions eBPF_Supermarket/Stack_Analyser/libbpf/bpf/mem_count.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@
#include "stack_analyzer.h"
#include "task.h"

BPF_HASH(psid_count, psid, u64);
//定义的哈希表以及堆栈跟踪对象
BPF_HASH(psid_count, psid, u64); //记录对应进程申请的总内存空间大小
BPF_STACK_TRACE(stack_trace);
BPF_HASH(pid_tgid, u32, u32);
BPF_HASH(pid_comm, u32, comm);

BPF_HASH(pid_size, u32, u64);
BPF_HASH(piddr_meminfo, piddr, mem_info);
BPF_HASH(pid_size, u32, u64); //记录了对应进程使用malloc,calloc等函数申请内存的大小
BPF_HASH(piddr_meminfo, piddr, mem_info); //记录了每次申请的内存空间的起始地址等信息

const char LICENSE[] SEC("license") = "GPL";

Expand All @@ -47,53 +48,58 @@ int gen_alloc_enter(size_t size)
// u64 pt = bpf_get_current_pid_tgid();
// u32 pid = pt >> 32;
// u32 tgid = pt;
struct task_struct *curr = (struct task_struct *)bpf_get_current_task();
struct task_struct *curr = (struct task_struct *)bpf_get_current_task(); //利用bpf_get_current_task()获得当前的进程tsk
u32 pid = get_task_ns_pid(curr); // also kernel pid, but attached ns pid on kernel pid, invaild!
u32 tgid = get_task_ns_tgid(curr);
bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY);
comm *p = bpf_map_lookup_elem(&pid_comm, &pid);
if (!p)
u32 tgid = get_task_ns_tgid(curr); //利用帮助函数获得当前进程的tgid
bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); //更新pid_tgid哈希表中的pid项目为tgid,如果该项不存在,则创建该表项
comm *p = bpf_map_lookup_elem(&pid_comm, &pid); //p指向pid_comm哈希表中的pid表项对应的value

if (!p) //如果p不为空,获取当前进程名保存至name中,如果pid_comm当中不存在pid => name项,则更新
{
comm name;
bpf_get_current_comm(&name, COMM_LEN);
bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST);
}

// record size
return bpf_map_update_elem(&pid_size, &pid, &size, BPF_ANY);
//size为挂载点传递的值
return bpf_map_update_elem(&pid_size, &pid, &size, BPF_ANY); //更新pid_size哈希表的pid项对应的值为size,如果不存在该项,则创建
}

SEC("uprobe/malloc")

SEC("uprobe/malloc") //用户空间探针uprobe,挂载点为malloc函数
int BPF_KPROBE(malloc_enter, size_t size)
{
return gen_alloc_enter(size);
return gen_alloc_enter(size); //当用户程序执行到malloc函数,则执行gen_alloc_enter(size)
}

SEC("uprobe/calloc")

SEC("uprobe/calloc") //用户空间探针uprobe,挂载点为calloc函数
int BPF_KPROBE(calloc_enter, size_t nmemb, size_t size)
{
return gen_alloc_enter(nmemb * size);
return gen_alloc_enter(nmemb * size); //当用户程序执行到calloc函数,则执行gen_alloc_enter(size)
}

SEC("uprobe/mmap")

SEC("uprobe/mmap") //用户空间探针uprobe,挂载点为mmap函数
int BPF_KPROBE(mmap_enter)
{
size_t size = PT_REGS_PARM2(ctx);
return gen_alloc_enter(size);
size_t size = PT_REGS_PARM2(ctx); //size为该函数的第二个参数的值
return gen_alloc_enter(size); //当用户程序执行到mmap函数,则执行gen_alloc_enter(size)
}

int gen_alloc_exit(struct pt_regs *ctx)
int gen_alloc_exit(struct pt_regs *ctx) //传入的参数ctx是个pt_regs(定义在vmlinux.h)的指针
{
void *addr = (void *)PT_REGS_RC(ctx);
void *addr = (void *)PT_REGS_RC(ctx); //从 struct pt_regs ctx 中提取函数的返回值
if (!addr)
return 0;
// bpf_printk("malloc_exit");
// get size
// u32 pid = bpf_get_current_pid_tgid() >> 32;
// struct task_struct* curr = ;
u32 pid = get_task_ns_pid((struct task_struct*)bpf_get_current_task());
u64 *size = bpf_map_lookup_elem(&pid_size, &pid);
if (!size)
u32 pid = get_task_ns_pid((struct task_struct*)bpf_get_current_task());//通过bpf_get_current_task函数得到当前进程的tsk。再通过get_task_ns_pid得到该进程的pid
u64 *size = bpf_map_lookup_elem(&pid_size, &pid); //size指向pid_size哈希表pid对应的值
if (!size) //size不存在
return -1;

// record stack count
Expand All @@ -102,57 +108,63 @@ int gen_alloc_exit(struct pt_regs *ctx)
.usid = u ? USER_STACK : -1,
.ksid = k ? KERNEL_STACK: -1,
};
u64 *count = bpf_map_lookup_elem(&psid_count, &apsid);
if (!count)
u64 *count = bpf_map_lookup_elem(&psid_count, &apsid);//count指向psid_count表apsid对应的值

if (!count) //如果count为空,,若表的apsid表项不存在,则更新psid_count表的apsid为size
bpf_map_update_elem(&psid_count, &apsid, size, BPF_NOEXIST);
else
(*count) += *size;
(*count) += *size; //psid_count表apsid对应的值+=pid_size哈希表pid对应的值


// record pid_addr-info
piddr a = {
.addr = (u64)addr,
.addr = (u64)addr, //函数的返回值
.pid = pid,
.o = 0,
};
mem_info info = {
.size = *size,
.usid = apsid.usid,
.usid = apsid.usid, //表示是在用户空间,因此设为用户栈
.o = 0,
};
return bpf_map_update_elem(&piddr_meminfo, &a, &info, BPF_NOEXIST);

return bpf_map_update_elem(&piddr_meminfo, &a, &info, BPF_NOEXIST);//如果表中不存在a这个表项,则更新piddr_meminfo表的a对应的值为info
}

SEC("uretprobe/malloc")

SEC("uretprobe/malloc") //用户空间探针uretprobe,挂载点为malloc函数
int BPF_KRETPROBE(malloc_exit)
{
return gen_alloc_exit(ctx);
return gen_alloc_exit(ctx); //当用户程序退出malloc函数,则执行gen_alloc_exit(ctx)
}

SEC("uretprobe/calloc")

SEC("uretprobe/calloc") //用户空间探针uretprobe,挂载点为calloc函数
int BPF_KRETPROBE(calloc_exit)
{
return gen_alloc_exit(ctx);
return gen_alloc_exit(ctx); //当用户程序退出clloc函数,则执行gen_alloc_exit(ctx)
}

SEC("uretprobe/realloc")
SEC("uretprobe/realloc") //用户空间探针uretprobe,挂载点为realloc函数
int BPF_KRETPROBE(realloc_exit)
{
return gen_alloc_exit(ctx);
return gen_alloc_exit(ctx); //当用户程序退出realloc函数,则执行gen_alloc_exit(ctx)
}

SEC("uretprobe/mmap")

SEC("uretprobe/mmap") //用户空间探针uretprobe,挂载点为mmap函数
int BPF_KRETPROBE(mmap_exit)
{
return gen_alloc_exit(ctx);
return gen_alloc_exit(ctx); //当用户程序退出mmap函数,则执行gen_alloc_exit(ctx)
}

int gen_free_enter(u64 addr, size_t unsize)
{
u32 pid = bpf_get_current_pid_tgid() >> 32;
u32 pid = bpf_get_current_pid_tgid() >> 32; //获取当前进程的pid
// struct task_struct* curr = (struct task_struct*)bpf_get_current_task();
// u32 pid = get_task_ns_pid(curr);
piddr a = {.addr = addr, .pid = pid, .o = 0};
mem_info *info = bpf_map_lookup_elem(&piddr_meminfo, &a);
mem_info *info = bpf_map_lookup_elem(&piddr_meminfo, &a); //info指向piddr_meminfo表中的a的值
if (!info)
return -1;

Expand All @@ -162,39 +174,46 @@ int gen_free_enter(u64 addr, size_t unsize)
.pid = pid,
.usid = info->usid,
};
u64 *size = bpf_map_lookup_elem(&psid_count, &apsid);

u64 *size = bpf_map_lookup_elem(&psid_count, &apsid); //size指向psid_count中apsid对应的值,即对应pid的总空间大小
if (!size)
return -1;

// sub the freeing size
//unsize为传入的值,是代表释放的空间大小
if(unsize) {
if (unsize >= *size)
*size = 0;

if (unsize >= *size) //unsize>=psid_count中apsid对应的值
*size = 0; //psid_count中apsid对应的值 = 0
else
(*size) -= unsize;
(*size) -= unsize; //否则,psid_count中apsid对应的值-=unsize
}
else
(*size) -= info->size;
(*size) -= info->size; //unsize=0,则psid_count中apsid对应的值-=piddr_meminfo表中的a的值的size成员的值

if(!*size) bpf_map_delete_elem(&psid_count, &apsid);

// del freeing addr info
return bpf_map_delete_elem(&piddr_meminfo, &a);
return bpf_map_delete_elem(&piddr_meminfo, &a); //删除piddr_meminfo表中的a的值,因为已经释放了
}

SEC("uprobe/free")

SEC("uprobe/free") //用户空间探针uprobe,挂载点为free函数
int BPF_KPROBE(free_enter, void *addr) {
return gen_free_enter((u64)addr, 0);
return gen_free_enter((u64)addr, 0); //当用户程序执行free函数,则执行gen_free_enter(addr, 0);
}

SEC("uprobe/realloc")

SEC("uprobe/realloc") //用户空间探针uprobe,挂载点为realloc函数
int BPF_KPROBE(realloc_enter, void *ptr, size_t size)
{
gen_free_enter((u64)ptr, 0);
gen_free_enter((u64)ptr, 0); //当用户程序执行realloc函数,则执行gen_free_enter(ptr, 0),并返回gen_alloc_enter(size)
return gen_alloc_enter(size);
}

SEC("uprobe/munmap")

SEC("uprobe/munmap") //用户空间探针uprobe,挂载点为munmap函数
int BPF_KPROBE(munmap_enter, void *addr, size_t unsize) {
return gen_free_enter((u64)addr, unsize);
return gen_free_enter((u64)addr, unsize); //当用户程序执行munmap函数,则执行gen_free_enter(addr, unsize);

}
Loading