#include "arguments.h"
#include "span_context.h"
#include "go_context.h"
#include "go_types.h"
#include "uprobe.h"

#define MAX_DATA_SIZE 64

#define ENTPOINT 0
#define RETPOINT 1

// bpf write event data when enter/exit a function
struct event
{
	__u64 type;
	__u64 pid;
	__u64 trace_id;
	__u64 goid;
	__u64 ip;
	__u64 bp;
	__u64 caller_ip;
	__u64 caller_bp;
	__u64 time_ns_start;
	__u64 time_ns_end;
	__u8 location;
	unsigned char class_name[100];
	unsigned char methed_name[100];
}__attribute__((packed));

struct trace_stack_entry_key_t {
	__u64 trace_id;
	__u64 caller_bp;
	__u64 bp;
};

struct {
    __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
    __uint(key_size, sizeof(int));
    __uint(value_size, sizeof(int));
	__uint(max_entries, 655351);
} event_queue SEC(".maps");

struct {
	__uint(type, BPF_MAP_TYPE_LRU_HASH);
	__uint(key_size, sizeof(struct trace_stack_entry_key_t));
	__uint(value_size, sizeof(struct event));
	__uint(max_entries, 32768);
} trace_stack_entry SEC(".maps");

struct {
	__uint(type, BPF_MAP_TYPE_LRU_HASH);
	__uint(key_size, sizeof(struct trace_stack_entry_key_t));
	__uint(value_size, sizeof(__u64));
	__uint(max_entries, 32768);
} trace_stack_entry_thread SEC(".maps");

struct bpf_map_def SEC("maps") event_stack = {
	.type = BPF_MAP_TYPE_PERCPU_ARRAY,
	.key_size = sizeof(__u32),
	.value_size = sizeof(struct event),
	.max_entries = 1,
};

struct bpf_map_def SEC("maps") should_trace_goid = {
	.type = BPF_MAP_TYPE_LRU_HASH,
	.key_size = sizeof(__u64),
	.value_size = sizeof(bool),
	.max_entries = 32768,
};

SEC("uprobe/ent")
int ent(struct pt_regs *ctx)
{
    cw_bpf_debug("[Go] [uprobe/ent] enter");
	__u64 pid_tgid = bpf_get_current_pid_tgid();
    __u64 pid = pid_tgid >> 32;

	struct ebpf_proc_info *info =
			bpf_map_lookup_elem(&proc_info_map, &pid);
	if (!info) {
		return 0;
	}

	cw_bpf_debug("[Go] [uprobe/ent]: proc_info_map::%ld, %d, %d\n", info->code_type);

	__u64 trace_id = get_apm_trace_id(pid, pid_tgid);

	cw_bpf_debug("[Go] [uprobe/ent]: get_apm_trace_id::%ld, %d, %d\n", trace_id, pid, pid_tgid);
	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][ent][HTTP]pid:[%d]--[%lld]--[%x]", pid_tgid, bpf_ktime_get_ns(), PT_REGS_IP(ctx));

	__u32 key = 0;
	struct event *e = bpf_map_lookup_elem(&event_stack, &key);
	if (!e)
	{
		cw_bpf_debug("[Go] [uprobe/ret]: conot get event");
		return 0;
	}
	__builtin_memset(e, 0, sizeof(*e));

	// e->goid = get_goid();
	e->goid = get_current_goroutine();

	// e->ip = ctx->ip;
	e->ip = PT_REGS_IP(ctx); // 当前函数的地址
	if (!bpf_map_lookup_elem(&should_trace_goid, &e->goid))
	{
		__u64 should_trace = true;
		bpf_map_update_elem(&should_trace_goid, &e->goid, &should_trace, BPF_ANY);
	}
	cw_bpf_debug("[Go] [uprobe/ent]: e->goid: %llu", e->goid);
	cw_bpf_debug("[Go] [uprobe/ent]: e->ip: %d", e->ip);
	cw_bpf_debug("[Go] [uprobe/ent]: yes");

	e->pid = pid;
	e->trace_id = trace_id;
	e->location = ENTPOINT; // 标识入口还是出口
	e->time_ns_start = bpf_ktime_get_ns();
	e->bp = PT_REGS_SP(ctx) - 8; // 因为 ebpf 程序执行时实际上还没进行堆栈的切换，所以此处是需要在父函数中获取子函数的基地址，新的堆栈会将父函数的 rbp 入栈，一个 rbp 在 64位机器上占用 8 个字节，所以需要减 8，获取到子函数的基地址，低地址的需要减8，如果到高地址的cpu 上就得+8
	e->caller_bp = PT_REGS_FP(ctx); // 父函数的基地址

	void *ra;
	ra = (void *)PT_REGS_SP(ctx); // 父函数的 sp，此时 sp 指向父函数的最后一个地址
	bpf_probe_read_user(&e->caller_ip, sizeof(e->caller_ip), ra);

	cw_bpf_debug("[Go] [uprobe/ent]: goid: %llu", e->goid);

	cw_bpf_debug("[Go] [uprobe/ent]: event: location:%x,ip:%lx,time_ns_start:%llu\n", e->location, e->ip, e->time_ns_start);
	cw_bpf_debug("[Go] [uprobe/ent]: event: bp:%x,caller_bp:%x,caller_ip:%x\n", e->bp,e->caller_bp,e->caller_ip);

	struct trace_stack_entry_key_t trace_key = {};
	trace_key.caller_bp = e->caller_bp % 0x800 + (e->goid << 12);
	trace_key.bp = e->bp % 0x800 + (e->goid << 12);
	trace_key.trace_id = trace_id;

	// trace_key.caller_bp = e->caller_bp;
	// trace_key.bp = e->bp;
	// cw_bpf_debug("[Go] [uprobe/ent]: trace_keytrace_keytrace_key: bp: %x", trace_key.bp);
	cw_bpf_debug("[Go] [uprobe/ent]: trace_keytrace_keytrace_key: caller_bp: %x, bp: %x, %lld", trace_key.caller_bp, trace_key.bp, trace_key.trace_id);

	struct event *event_p = bpf_map_lookup_elem(&trace_stack_entry, &trace_key);

	if (event_p) {
		cw_bpf_debug("[Go] [uprobe/ent]:Error get alike funEntry %x, %x, %x", event_p->ip, event_p->caller_bp, event_p->bp);
		// return 0;
	}

	struct event event_current = {};
	event_current.bp = e->bp,
	event_current.caller_bp = e->caller_bp,
	event_current.caller_ip = e->caller_ip,
	event_current.pid = e->pid,
	event_current.trace_id = e->trace_id,
	event_current.goid = e->goid,
	event_current.ip = e->ip,
	event_current.time_ns_start = e->time_ns_start,
	event_current.location = e->location,

	bpf_map_update_elem(&trace_stack_entry, &trace_key, &event_current, BPF_ANY);

	// return bpf_map_push_elem(&event_queue, e, BPF_EXIST);
	// bpf_perf_event_output(ctx, &event_queue, BPF_F_CURRENT_CPU, e, sizeof(*e));

	cw_bpf_debug("[Go] [uprobe/ent] end");
	return 1;
}

SEC("uprobe/ret")
int ret(struct pt_regs *ctx)
{
    cw_bpf_debug("[Go] [uprobe/ret] enter");
	__u64 pid_tgid = bpf_get_current_pid_tgid();
    __u64 pid = pid_tgid >> 32;

	__u64 trace_id = get_apm_trace_id(pid, pid_tgid);

	__u32 key = 0;
	struct event *e = bpf_map_lookup_elem(&event_stack, &key);
	if (!e)
	{
		cw_bpf_debug("[Go] [uprobe/ret]: conot get event");
		return 0;
	}
	__builtin_memset(e, 0, sizeof(*e));

	// e->goid = get_goid();
	e->goid = get_current_goroutine();
	if (!bpf_map_lookup_elem(&should_trace_goid, &e->goid))
	{
		cw_bpf_debug("[Go] [uprobe/ret]: conot get event: %llu", e->goid);
		return 0;
	}
	cw_bpf_debug("[Go] [uprobe/ret]: yes");
	e->pid = pid;
	e->trace_id = trace_id;
	e->location = ENTPOINT;
	e->ip = PT_REGS_IP(ctx);
	e->time_ns_end = bpf_ktime_get_ns();
	e->bp = PT_REGS_SP(ctx) - 8;
	e->caller_bp = PT_REGS_FP(ctx);

	// __u64 caller_bp = PT_REGS_FP(ctx);
	cw_bpf_debug("[Go] [uprobe/ret]: e->ip:%lx,bp:%x,caller_bp:%x", e->ip, e->bp, e->caller_bp);
	cw_bpf_debug("[Go] [uprobe/ret]: sp:%x, goid: %llu, goid:0x:%x", PT_REGS_SP(ctx), e->goid, e->goid);

	cw_bpf_debug("[Go] [uprobe/ret]: event: location:%x,ip:%x,time_ns_end:%llu\n", e->location, e->ip, e->time_ns_end);

	struct trace_stack_entry_key_t trace_key = {};
	trace_key.caller_bp = e->caller_bp % 0x800 + (e->goid << 12);
	trace_key.bp = e->bp % 0x800 + (e->goid << 12);
	trace_key.trace_id = trace_id;

	// trace_key.caller_bp = caller_bp;
	// trace_key.bp = e->bp;

	cw_bpf_debug("[Go] [uprobe/ret]: trace_keytrace_keytrace_key: caller_bp: %x, bp: %x", trace_key.caller_bp, trace_key.bp);
	// cw_bpf_debug("[Go] [uprobe/ret]: trace_keytrace_keytrace_key: bp: %x", trace_key.bp);

	struct event *event_p = bpf_map_lookup_elem(&trace_stack_entry, &trace_key);

	if (!event_p) {
		cw_bpf_debug("[Go] [uprobe/ret]:ErrorErrorErrorError Not get funEntry");
		return 0;
	}

	event_p->time_ns_end = e->time_ns_end;

	cw_bpf_debug("[Go] [uprobe/ret]: ent:event: location:%d,ip:%x,time_ns_start:%llu\n", event_p->location, event_p->ip, event_p->time_ns_start);
	cw_bpf_debug("[Go] [uprobe/ret]: ent:event: bp:%x,caller_bp:%x,caller_ip:%x\n", event_p->bp,event_p->caller_bp,event_p->caller_ip);

	e->time_ns_start = event_p->time_ns_start;
	// e->caller_ip = event_p->caller_ip;
	// e->ip = event_p->ip;
	
	// return bpf_map_push_elem(&event_queue, e, BPF_EXIST);
	cw_bpf_debug("[Go] [uprobe/ret]: ent:event_ret push: event_p->ip:%llx,ip:%llx\n", event_p->ip, e->ip);
	long err =  bpf_perf_event_output(ctx, &event_queue, BPF_F_CURRENT_CPU, e, sizeof(*e));
	if (err == 0) {
		__u32 count = cw_add_event_count(trace_id);
		if (event_p->trace_id != trace_id) {
			cw_bpf_debug("[pref] fuck err<%d> ip->%x->%x", err, PT_REGS_IP(ctx), e->ip);
		}
		cw_bpf_debug("[pref] err<%d> count->%d trace_id->%llu", err, count, trace_id);
	} else {
		cw_bpf_debug("[pref] err<%d> trace_id->%d", err, trace_id);
	}
	bpf_map_delete_elem(&trace_stack_entry, &trace_key);
	cw_bpf_debug("[Go] [uprobe/ret] end");
	return 1;
}

SEC("uprobe/dotnetent")
int dotnetent(struct pt_regs *ctx)
{
    cw_bpf_debug("[Go] [uprobe/ent] enter");
	__u64 pid_tgid = bpf_get_current_pid_tgid();
    __u64 pid = pid_tgid >> 32;

	struct ebpf_proc_info *info =
			bpf_map_lookup_elem(&proc_info_map, &pid);
	if (!info) {
		return 0;
	}

	cw_bpf_debug("[Go] [uprobe/ent]: proc_info_map::%ld, %d, %d\n", info->code_type);

	__u64 trace_id = get_apm_trace_id(pid, pid_tgid);
	
	cw_bpf_debug("[Go] [uprobe/ent]: get_apm_trace_id::%ld, %d, %d\n", trace_id, pid, pid_tgid);
	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][ent][HTTP]pid:[%d]--[%lld]--[%x]", pid_tgid, bpf_ktime_get_ns(), PT_REGS_IP(ctx));

	__u32 key = 0;
	struct event *e = bpf_map_lookup_elem(&event_stack, &key);
	if (!e)
	{
		cw_bpf_debug("[Go] [uprobe/ret]: conot get event");
		return 0;
	}
	__builtin_memset(e, 0, sizeof(*e));

	// e->goid = get_goid();
	e->goid = get_current_goroutine();

	// e->ip = ctx->ip;
	e->ip = PT_REGS_IP(ctx); // 当前函数的地址
	if (!bpf_map_lookup_elem(&should_trace_goid, &e->goid))
	{
		__u64 should_trace = true;
		bpf_map_update_elem(&should_trace_goid, &e->goid, &should_trace, BPF_ANY);
	}
	cw_bpf_debug("[Go] [uprobe/ent]: e->goid: %llu", e->goid);
	cw_bpf_debug("[Go] [uprobe/ent]: e->ip: %d", e->ip);
	cw_bpf_debug("[Go] [uprobe/ent]: yes");

	__u64 asm_;
	bpf_probe_read_user(&asm_, sizeof(asm_), (void*)e->ip);

	asm_ = asm_ >> 32;
	cw_bpf_debug("[Go] [uprobe/ent]: e->asm: %x", asm_);

	e->pid = pid;
	e->trace_id = trace_id;
	e->location = ENTPOINT; // 标识入口还是出口
	e->time_ns_start = bpf_ktime_get_ns();
	e->bp = PT_REGS_SP(ctx) + asm_; // 因为 ebpf 程序执行时实际上还没进行堆栈的切换，所以此处是需要在父函数中获取子函数的基地址，新的堆栈会将父函数的 rbp 入栈，一个 rbp 在 64位机器上占用 8 个字节，所以需要减 8，获取到子函数的基地址，低地址的需要减8，如果到高地址的cpu 上就得+8
	e->caller_bp = PT_REGS_FP(ctx); // 父函数的基地址

	void *ra;
	ra = (void *)PT_REGS_SP(ctx); // 父函数的 sp，此时 sp 指向父函数的最后一个地址
	bpf_probe_read_user(&e->caller_ip, sizeof(e->caller_ip), ra);

	cw_bpf_debug("[Go] [uprobe/ent]: goid: %llu", e->goid);

	cw_bpf_debug("[Go] [uprobe/ent]: event: location:%x,ip:%lx,time_ns_start:%lld\n", e->location, e->ip, e->time_ns_start);
	cw_bpf_debug("[Go] [uprobe/ent]: event: bp:%x,caller_bp:%x,caller_ip:%x\n", e->bp,e->caller_bp,e->caller_ip);

	struct trace_stack_entry_key_t trace_key = {};
	trace_key.caller_bp = e->caller_bp % 0x800 + (e->goid << 12);
	trace_key.bp = e->bp % 0x800 + (e->goid << 12);
	trace_key.trace_id = trace_id;

	// trace_key.caller_bp = e->caller_bp;
	// trace_key.bp = e->bp;
	// cw_bpf_debug("[Go] [uprobe/ent]: trace_keytrace_keytrace_key: bp: %x", trace_key.bp);
	cw_bpf_debug("[Go] [uprobe/ent]: trace_keytrace_keytrace_key: caller_bp: %x, bp: %x", trace_key.caller_bp, trace_key.bp);

	struct event event_current = {};
	event_current.bp = e->bp,
	event_current.caller_bp = e->caller_bp,
	event_current.caller_ip = e->caller_ip,
	event_current.pid = e->pid,
	event_current.trace_id = e->trace_id,
	event_current.goid = e->goid,
	event_current.ip = e->ip,
	event_current.time_ns_start = e->time_ns_start,
	event_current.location = e->location,

	bpf_map_update_elem(&trace_stack_entry, &trace_key, &event_current, BPF_ANY);

	// return bpf_map_push_elem(&event_queue, e, BPF_EXIST);
	// bpf_perf_event_output(ctx, &event_queue, BPF_F_CURRENT_CPU, e, sizeof(*e));

	cw_bpf_debug("[Go] [uprobe/ent] end");
	return 1;
}

SEC("uprobe/SocketConnectionStartStart")
int SocketConnectionStartStart(struct pt_regs *ctx)
{
	cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartStart] enter");
	__u64 pid_tgid = bpf_get_current_pid_tgid();
    __u64 pid = pid_tgid >> 32;

	__u64 rdi_ptr = (__u64)PT_REGS_PARM1(ctx);
	// __u64 rdi_ptr_long = (__u64)rdi_ptr;

	cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartStart]: rdi_ptr:: %llx\n", rdi_ptr);
	// cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartStart]: rdi_ptr:: %llx\n", rdi_ptr_long);
	cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartStart]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][SocketConnectionStartStart][HTTP]pid:[%d]--[%lld]--request[%llx]", pid_tgid, bpf_ktime_get_ns(), rdi_ptr);

	// 维护 pid 与 connection 的关系
	int num = 1;
	struct pid_of_connection_ptr_key_t *pre_e = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, &pid);
	if (pre_e) {
		cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartStart]getget: rdi_ptr:: %llx -> %d\n", pre_e->connection_ptr, pre_e->num);
		num = pre_e->num + 1;
	}
	struct pid_of_connection_ptr_key_t connection_ptr_key = {};
	connection_ptr_key.num = num;
	connection_ptr_key.connection_ptr = rdi_ptr;
	bpf_map_update_elem(&pid_of_connection_ptr_maps, &pid, &connection_ptr_key, BPF_ANY);
	cw_bpf_debug("[Go] [uprobeThread/insert/SocketConnectionStartStart]getget: rdi_ptr:: %d -> %llx\n", pid, rdi_ptr);

	struct pid_of_connection_ptr_key_t *e = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, &pid);
	if (!e) {
		cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartStart]getget: ErrorErrorErrorError rdi_ptr\n");
		return 0;
	}
	cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartStart]getget: rdi_ptr:: %llx -> %d\n", e->connection_ptr, e->num);
	// 维护 pid 与 connection 的关系


	// 维护函数出入口，用于关闭 当前 Connection 与线程的关系
	__u64 ip = PT_REGS_IP(ctx);
	__u64 asm_;
	bpf_probe_read_user(&asm_, sizeof(asm_), (void*)ip);

	asm_ = asm_ >> 32;
	cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartStart/ent]: e->asm: %x", asm_);

	__u64 bp = PT_REGS_SP(ctx);
	// __u64 bp = PT_REGS_SP(ctx) + asm_;
	__u64 caller_bp = PT_REGS_FP(ctx);

	struct trace_stack_entry_key_t trace_key = {};
	trace_key.caller_bp = caller_bp;
	trace_key.bp = bp;
	trace_key.trace_id = 0;

	cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartStart/ent]: trace_keytrace_keytrace_key: rbp: %x, rbp: %x, rip:%x", PT_REGS_FP(ctx), PT_REGS_SP(ctx), PT_REGS_IP(ctx));
	cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartStart/ent]: trace_keytrace_keytrace_key: caller_bp: %x, bp: %x", trace_key.caller_bp, trace_key.bp);

	bpf_map_update_elem(&trace_stack_entry_thread, &trace_key, &pid, BPF_ANY);
	// 维护函数出入口，用于关闭 当前 Connection 与线程的关系
	
	return 1;
}

SEC("uprobe/SocketConnectionStartEnd")
int SocketConnectionStartEnd(struct pt_regs *ctx)
{
	cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartEnd] enter");
	__u64 pid_tgid = bpf_get_current_pid_tgid();
    __u64 pid = pid_tgid >> 32;

	cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartEnd]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][SocketConnectionStartEnd][HTTP]pid:[%d]--[%lld]", pid_tgid, bpf_ktime_get_ns());


	// 维护函数出入口，用于关闭 当前 Connection 与线程的关系
	// __u64 bp = PT_REGS_SP(ctx) - 8;
	__u64 bp = PT_REGS_SP(ctx);
	__u64 caller_bp = PT_REGS_FP(ctx);

	struct trace_stack_entry_key_t trace_key = {};
	trace_key.caller_bp = caller_bp;
	trace_key.bp = bp;
	trace_key.trace_id = 0;

	cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartEnd/ent]: trace_keytrace_keytrace_key: rbp: %x, rbp: %x, rip: %x", PT_REGS_FP(ctx), PT_REGS_SP(ctx), PT_REGS_IP(ctx));
	cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartEnd]: trace_keytrace_keytrace_key: caller_bp: %x, bp: %x", trace_key.caller_bp, trace_key.bp);

	__u64 *pid_p = bpf_map_lookup_elem(&trace_stack_entry_thread, &trace_key);

	if (!pid_p) {
		cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartEnd]:ErrorErrorErrorError Not get funEntry");
		return 0;
	}
	cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartEnd]:Delete It: %d", *pid_p);
	bpf_map_delete_elem(&trace_stack_entry_thread, &trace_key);

	// 删除 pid 与 connection 的关系，由于 hook 点可能共用同一个线程，需要维护 num
	struct pid_of_connection_ptr_key_t *ed_e = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, pid_p);
	if (ed_e && ed_e->num > 1) {
		cw_bpf_debug("[Go] [uprobeThread/SocketConnectionStartEnd]getget: rdi_ptr:: %llx -> %d\n", ed_e->connection_ptr, ed_e->num);
		ed_e->num = ed_e->num - 1;
		bpf_map_update_elem(&pid_of_connection_ptr_maps, pid_p, ed_e, BPF_ANY);
	} else {
		bpf_map_delete_elem(&pid_of_connection_ptr_maps, pid_p);
	}
	cw_bpf_debug("[Go] [uprobeThread/delete/SocketConnectionStartEnd]getget: rdi_ptr:: %d\n", *pid_p);
	// 维护函数出入口，用于关闭 当前 Connection 与线程的关系
	return 1;
}


SEC("uprobe/OnConnectionAsyncStart")
int OnConnectionAsyncStart(struct pt_regs *ctx)
{
	cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncStart] enter");
	__u64 pid_tgid = bpf_get_current_pid_tgid();
    __u64 pid = pid_tgid >> 32;


    __u64 rsi_ptr = (__u64)PT_REGS_PARM2(ctx);  

	cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncStart]: rsi_ptr:: %llx\n", rsi_ptr);
	cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncStart]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);

	// 维护 pid 与 connection 的关系
	int num = 1;
	struct pid_of_connection_ptr_key_t *pre_e = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, &pid);
	if (pre_e) {
		cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncStart]getget: rdi_ptr:: %llx -> %d\n", pre_e->connection_ptr, pre_e->num);
		num = pre_e->num + 1;
	}
	struct pid_of_connection_ptr_key_t connection_ptr_key = {};
	connection_ptr_key.num = num;
	connection_ptr_key.connection_ptr = rsi_ptr;
	bpf_map_update_elem(&pid_of_connection_ptr_maps, &pid, &connection_ptr_key, BPF_ANY);
	cw_bpf_debug("[Go] [uprobeThread/insert/OnConnectionAsyncStart]getget: rdi_ptr:: %d -> %llx\n", pid, rsi_ptr);

	struct pid_of_connection_ptr_key_t *e3 = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, &pid);
	if (!e3) {
		cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncStart]getget: ErrorErrorErrorError rsi_ptr3\n");
		return 0;
	}
	cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncStart]getget: rsi_ptr3:: %llx -> %d\n", e3->connection_ptr, e3->num);
	// 维护 pid 与 connection 的关系
	return 1;
}

SEC("uprobe/OnConnectionAsyncEnd")
int OnConnectionAsyncEnd(struct pt_regs *ctx)
{
	cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncEnd] enter");
	__u64 pid_tgid = bpf_get_current_pid_tgid();
    __u64 pid = pid_tgid >> 32;

	cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncEnd]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][OnConnectionAsyncEnd][HTTP]pid:[%d]--[%lld]", pid_tgid, bpf_ktime_get_ns());

	// 维护 pid 与 connection 的关系
	__u64 *e3 = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, &pid);
	if (!e3) {
		cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncEnd]getget: rsi_ptr:: %llx\n", *e3);
		return 0;
	}
	cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncEnd]getget: rsi_ptr:: %llx\n", *e3);

	// 删除 pid 与 connection 的关系，由于 hook 点可能共用同一个线程，需要维护 num
	struct pid_of_connection_ptr_key_t *ed_e = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, &pid);
	if (ed_e && ed_e->num > 1) {
		cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncEnd]getget: rdi_ptr:: %llx -> %d\n", ed_e->connection_ptr, ed_e->num);
		ed_e->num = ed_e->num - 1;
		bpf_map_update_elem(&pid_of_connection_ptr_maps, &pid, ed_e, BPF_ANY);
	} else {
		bpf_map_delete_elem(&pid_of_connection_ptr_maps, &pid);
	}
	cw_bpf_debug("[Go] [uprobeThread/delete/OnConnectionAsyncEnd]getget: rdi_ptr:: %d\n", pid);
	// 维护 pid 与 connection 的关系
	return 1;
}

struct {
	__uint(type, BPF_MAP_TYPE_HASH);
	__uint(key_size, sizeof(__u64));
	__uint(value_size, sizeof(__u64));
	__uint(max_entries, 10240);
} request_of_connection_ptr_maps SEC(".maps");

SEC("uprobe/SendAsync1Start")
int SendAsync1Start(struct pt_regs *ctx)
{
	cw_bpf_debug("[Go] [uprobeTshread/SendAsync1Start] enter");
	__u64 pid_tgid = bpf_get_current_pid_tgid();
    __u64 pid = pid_tgid >> 32;

	void *rsi_ptr = (void *)PT_REGS_PARM2(ctx);

	cw_bpf_debug("[Go] [uprobeThread/SendAsync1Start]: rsi_ptr:: %llx\n", rsi_ptr);

	cw_bpf_debug("[Go] [uprobeThread/SendAsync1Start]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][SendAsync1Start][HTTP]pid:[%d]--[%lld]--request[%llx]", pid_tgid, bpf_ktime_get_ns(), rsi_ptr);

	// 维护 pid 与 connection 的关系
	__u64 *e3 = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, &pid);
	if (!e3) {
		cw_bpf_debug("[Go] [uprobeThread/SendAsync1Start]getget: rsi_ptr:: %llx\n", *e3);
		return 0;
	}
	cw_bpf_debug("[Go] [uprobeThread/SendAsync1Start]getget: rsi_ptr:: %llx\n", *e3);

	bpf_map_update_elem(&request_of_connection_ptr_maps, &rsi_ptr, e3, BPF_ANY);

	__u64 *e2 = bpf_map_lookup_elem(&request_of_connection_ptr_maps, &rsi_ptr);
	if (!e2) {
		cw_bpf_debug("[Go] [uprobeThread/SendAsync1Start] ErrorErrorError getget: rsi_ptr2:: %llx\n", *e2);
		return 0;
	}
	cw_bpf_debug("[Go] [uprobeThread/SendAsync1Start]getget: rsi_ptr2:: %llx\n", *e2);
	// 维护 pid 与 connection 的关系

	return 1;
}

SEC("uprobe/SendAsync1End")
int SendAsync1End(struct pt_regs *ctx)
{
	cw_bpf_debug("[Go] [uprobeTshread/SendAsync1End] enter");
	return 1;
}

SEC("uprobe/SendAsync2Start")
int SendAsync2Start(struct pt_regs *ctx)
{
	cw_bpf_debug("[Go] [uprobeThread/SendAsync2Start] enter");
	__u64 pid_tgid = bpf_get_current_pid_tgid();
    __u64 pid = pid_tgid >> 32;

	void *rdi_ptr = (void *)PT_REGS_PARM1(ctx);

	void* fd_ptr;
    if (bpf_probe_read(&fd_ptr, sizeof(fd_ptr), rdi_ptr + 0x8)) {
        // return 1;
    }

	cw_bpf_debug("[Go] [uprobeThread/SendAsync2Start]: fd_ptr:: %llx\n", fd_ptr);

	cw_bpf_debug("[Go] [uprobeThread/SendAsync2Start]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][SendAsync2Start][HTTP]pid:[%d]--[%lld]--request[%llx]", pid_tgid, bpf_ktime_get_ns(), fd_ptr);


	// 维护 pid 与 connection 的关系
	__u64 *e2 = bpf_map_lookup_elem(&request_of_connection_ptr_maps, &fd_ptr);
	if (!e2) {
		cw_bpf_debug("[Go] [uprobeThread/SendAsync2Start] ErrorErrorError getget: fd_ptr:: %llx\n", *e2);
		return 0;
	}
	cw_bpf_debug("[Go] [uprobeThread/SendAsync2Start]getget: fd_ptr:: %llx\n", *e2);

	int num = 1;
	struct pid_of_connection_ptr_key_t *pre_e = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, &pid);
	if (pre_e) {
		cw_bpf_debug("[Go] [uprobeThread/SendAsync2Start]getget: rdi_ptr:: %llx -> %d\n", pre_e->connection_ptr, pre_e->num);
		num = pre_e->num + 1;
	}
	struct pid_of_connection_ptr_key_t connection_ptr_key = {};
	connection_ptr_key.num = num;
	connection_ptr_key.connection_ptr = *e2;
	bpf_map_update_elem(&pid_of_connection_ptr_maps, &pid, &connection_ptr_key, BPF_ANY);
	cw_bpf_debug("[Go] [uprobeThread/insert/SendAsync2Start]getget: rdi_ptr:: %d -> %llx\n", pid, *e2);

	struct pid_of_connection_ptr_key_t *e3 = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, &pid);
	if (!e3) {
		cw_bpf_debug("[Go] [uprobeThread/SendAsync2Start]getget: ErrorErrorErrorError rsi_ptr3\n");
		return 0;
	}
	cw_bpf_debug("[Go] [uprobeThread/SendAsync2Start]getget: rsi_ptr3:: %llx -> %d\n", e3->connection_ptr, e3->num);
	// 维护 pid 与 connection 的关系


	// 维护函数出入口，用于关闭 当前 Connection 与线程的关系
	__u64 ip = PT_REGS_IP(ctx);
	__u64 asm_;
	bpf_probe_read_user(&asm_, sizeof(asm_), (void*)ip);

	asm_ = asm_ >> 32;
	cw_bpf_debug("[Go] [uprobeThread/SendAsync2Start/ent]: e->asm: %x", asm_);

	__u64 bp = PT_REGS_SP(ctx);
	// __u64 bp = PT_REGS_SP(ctx) + asm_;
	__u64 caller_bp = PT_REGS_FP(ctx);

	struct trace_stack_entry_key_t trace_key = {};
	trace_key.caller_bp = caller_bp;
	trace_key.bp = bp;
	trace_key.trace_id = 0;

	cw_bpf_debug("[Go] [uprobeThread/SendAsync2Start/ent]: trace_keytrace_keytrace_key: rbp: %x, rbp: %x, rip:%x", PT_REGS_FP(ctx), PT_REGS_SP(ctx), PT_REGS_IP(ctx));
	cw_bpf_debug("[Go] [uprobeThread/SendAsync2Start/ent]: trace_keytrace_keytrace_key: caller_bp: %x, bp: %x", trace_key.caller_bp, trace_key.bp);

	bpf_map_update_elem(&trace_stack_entry_thread, &trace_key, &pid, BPF_ANY);
	// 维护函数出入口，用于关闭 当前 Connection 与线程的关系

	return 1;
}

SEC("uprobe/SendAsync2End")
int SendAsync2End(struct pt_regs *ctx)
{
	cw_bpf_debug("[Go] [uprobeThread/SendAsync2End] enter");
	__u64 pid_tgid = bpf_get_current_pid_tgid();
    __u64 pid = pid_tgid >> 32;

	cw_bpf_debug("[Go] [uprobeThread/SendAsync2End]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][SendAsync2End][HTTP]pid:[%d]--[%lld]", pid_tgid, bpf_ktime_get_ns());

	// 维护函数出入口，用于关闭 当前 Connection 与线程的关系
	// __u64 bp = PT_REGS_SP(ctx) - 8;
	__u64 bp = PT_REGS_SP(ctx);
	__u64 caller_bp = PT_REGS_FP(ctx);

	struct trace_stack_entry_key_t trace_key = {};
	trace_key.caller_bp = caller_bp;
	trace_key.bp = bp;
	trace_key.trace_id = 0;

	cw_bpf_debug("[Go] [uprobeThread/SendAsync2End/ent]: trace_keytrace_keytrace_key: rbp: %x, rbp: %x, rip: %x", PT_REGS_FP(ctx), PT_REGS_SP(ctx), PT_REGS_IP(ctx));
	cw_bpf_debug("[Go] [uprobeThread/SendAsync2End/ent]: trace_keytrace_keytrace_key: caller_bp: %x, bp: %x", trace_key.caller_bp, trace_key.bp);

	__u64 *pid_p = bpf_map_lookup_elem(&trace_stack_entry_thread, &trace_key);

	if (!pid_p) {
		cw_bpf_debug("[Go] [uprobeThread/SendAsync2End/ent]:ErrorErrorErrorError Not get funEntry");
		return 0;
	}
	cw_bpf_debug("[Go] [uprobeThread/SendAsync2End/ent]:Delete It: %d", *pid_p);
	bpf_map_delete_elem(&trace_stack_entry_thread, &trace_key);

	// 删除 pid 与 connection 的关系，由于 hook 点可能共用同一个线程，需要维护 num
	struct pid_of_connection_ptr_key_t *ed_e = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, pid_p);
	if (ed_e && ed_e->num > 1) {
		cw_bpf_debug("[Go] [uprobeThread/SendAsync2End]getget: rdi_ptr:: %llx -> %d\n", ed_e->connection_ptr, ed_e->num);
		ed_e->num = ed_e->num - 1;
		bpf_map_update_elem(&pid_of_connection_ptr_maps, pid_p, ed_e, BPF_ANY);
	} else {
		bpf_map_delete_elem(&pid_of_connection_ptr_maps, pid_p);
	}
	cw_bpf_debug("[Go] [uprobeThread/delete/SendAsync2End]getget: rdi_ptr:: %d\n", pid_p);
	// 维护函数出入口，用于关闭 当前 Connection 与线程的关系

	return 1;
}

SEC("uprobe/DoSendStart")
int DoSendStart(struct pt_regs *ctx)
{
	cw_bpf_debug("[Go] [uprobeThread/DoSendStart] enter");
	__u64 pid_tgid = bpf_get_current_pid_tgid();
    __u64 pid = pid_tgid >> 32;
	

	void *rdi_ptr = (void *)PT_REGS_PARM1(ctx);

	__u64 fd_ptr;
    if (bpf_probe_read(&fd_ptr, sizeof(fd_ptr), rdi_ptr - 0xe8 + 0x28)) {
        // return 1;
    }
	cw_bpf_debug("[Go] [uprobeThread/DoSendStart]: fd_ptr: %llx\n", fd_ptr);  
	cw_bpf_debug("[Go] [uprobeThread/DoSendStart]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
	// cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][DoSendStart][HTTP]pid:[%d]--[%lld]--id[%s]", pid_tgid, bpf_ktime_get_ns(), final_connection_id);

	// 维护 pid 与 connection 的关系
	int num = 1;
	struct pid_of_connection_ptr_key_t *pre_e = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, &pid);
	if (pre_e) {
		cw_bpf_debug("[Go] [uprobeThread/DoSendStart]getget: rdi_ptr:: %llx -> %d\n", pre_e->connection_ptr, pre_e->num);
		num = pre_e->num + 1;
	}
	struct pid_of_connection_ptr_key_t connection_ptr_key = {};
	connection_ptr_key.num = num;
	connection_ptr_key.connection_ptr = fd_ptr;
	bpf_map_update_elem(&pid_of_connection_ptr_maps, &pid, &connection_ptr_key, BPF_ANY);
	cw_bpf_debug("[Go] [uprobeThread/insert/DoSendStart]getget: rdi_ptr:: %d -> %llx\n", pid, fd_ptr);

	struct pid_of_connection_ptr_key_t *e3 = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, &pid);
	if (!e3) {
		cw_bpf_debug("[Go] [uprobeThread/DoSendStart] ErrorErrorError getget: rsi_ptr3\n");
		return 0;
	}
	cw_bpf_debug("[Go] [uprobeThread/DoSendStart]getget: rsi_ptr3:: %llx -> %d\n", e3->connection_ptr, e3->num);
	// 维护 pid 与 connection 的关系


	// 维护函数出入口，用于关闭 当前 Connection 与线程的关系
	__u64 ip = PT_REGS_IP(ctx);
	__u64 asm_;
	bpf_probe_read_user(&asm_, sizeof(asm_), (void*)ip);

	asm_ = asm_ >> 32;
	cw_bpf_debug("[Go] [uprobeThread/DoSendStart/ent]: e->asm: %x", asm_);

	__u64 bp = PT_REGS_SP(ctx);
	// __u64 bp = PT_REGS_SP(ctx) + asm_;
	__u64 caller_bp = PT_REGS_FP(ctx);

	struct trace_stack_entry_key_t trace_key = {};
	trace_key.caller_bp = caller_bp;
	trace_key.bp = bp;
	trace_key.trace_id = 0;

	cw_bpf_debug("[Go] [uprobeThread/DoSendStart/ent]: trace_keytrace_keytrace_key: rbp: %x, rbp: %x, rip:%x", PT_REGS_FP(ctx), PT_REGS_SP(ctx), PT_REGS_IP(ctx));
	cw_bpf_debug("[Go] [uprobeThread/DoSendStart/ent]: trace_keytrace_keytrace_key: caller_bp: %x, bp: %x", trace_key.caller_bp, trace_key.bp);

	bpf_map_update_elem(&trace_stack_entry_thread, &trace_key, &pid, BPF_ANY);
	// 维护函数出入口，用于关闭 当前 Connection 与线程的关系

	return 1;
}

SEC("uprobe/DoSendEnd")
int DoSendEnd(struct pt_regs *ctx)
{
	cw_bpf_debug("[Go] [uprobeThread/DoSendEnd] enter");
	__u64 pid_tgid = bpf_get_current_pid_tgid();
    __u64 pid = pid_tgid >> 32;

	cw_bpf_debug("[Go] [uprobeThread/DoSendEnd]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][DoSendEnd][HTTP]pid:[%d]--[%lld]", pid_tgid, bpf_ktime_get_ns());

	// 维护函数出入口，用于关闭 当前 Connection 与线程的关系
	// __u64 bp = PT_REGS_SP(ctx) - 8;
	__u64 bp = PT_REGS_SP(ctx);
	__u64 caller_bp = PT_REGS_FP(ctx);

	struct trace_stack_entry_key_t trace_key = {};
	trace_key.caller_bp = caller_bp;
	trace_key.bp = bp;
	trace_key.trace_id = 0;

	cw_bpf_debug("[Go] [uprobeThread/DoSendEnd/ret]: trace_keytrace_keytrace_key: rbp: %x, rbp: %x, rip: %x", PT_REGS_FP(ctx), PT_REGS_SP(ctx), PT_REGS_IP(ctx));
	cw_bpf_debug("[Go] [uprobeThread/DoSendEnd/ret]: trace_keytrace_keytrace_key: caller_bp: %x, bp: %x", trace_key.caller_bp, trace_key.bp);

	__u64 *pid_p = bpf_map_lookup_elem(&trace_stack_entry_thread, &trace_key);

	if (!pid_p) {
		cw_bpf_debug("[Go] [uprobeThread/DoSendEnd/ret]:ErrorErrorErrorError Not get funEntry");
		return 0;
	}
	cw_bpf_debug("[Go] [uprobeThread/DoSendEnd/ret]:Delete It: %d", *pid_p);
	bpf_map_delete_elem(&trace_stack_entry_thread, &trace_key);

	// 删除 pid 与 connection 的关系，由于 hook 点可能共用同一个线程，需要维护 num
	struct pid_of_connection_ptr_key_t *ed_e = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, pid_p);
	if (ed_e && ed_e->num > 1) {
		cw_bpf_debug("[Go] [uprobeThread/DoSendEnd]getget: rdi_ptr:: %llx -> %d\n", ed_e->connection_ptr, ed_e->num);
		ed_e->num = ed_e->num - 1;
		bpf_map_update_elem(&pid_of_connection_ptr_maps, pid_p, ed_e, BPF_ANY);
	} else {
		bpf_map_delete_elem(&pid_of_connection_ptr_maps, pid_p);
	}
	cw_bpf_debug("[Go] [uprobeThread/delete/DoSendEnd]getget: rdi_ptr:: %d\n", pid_p);
	// 维护函数出入口，用于关闭 当前 Connection 与线程的关系

	return 1;
}



// 以下 V1 版本使用 ConnectionId 串联使用，如果用直接用 Connection 对象可缩减部分逻辑
// SEC("uprobe/CreateContextStart")
// int CreateContextStart(struct pt_regs *ctx)
// {
// 	cw_bpf_debug("[Go] [uprobeThread/CreateContextStart] enter");
// 	__u64 pid_tgid = bpf_get_current_pid_tgid();
//     __u64 pid = pid_tgid >> 32;

// 	void *rsi_ptr = (void *)PT_REGS_PARM2(ctx);

// 	cw_bpf_debug("[Go] [uprobeThread/CreateContextStart]: rdi_ptr:: %llx\n", rsi_ptr);
// 	cw_bpf_debug("[Go] [uprobeThread/CreateContextStart]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
// 	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][CreateContextStart][HTTP]pid:[%d]--[%lld]--request[%llx]", pid_tgid, bpf_ktime_get_ns(), rsi_ptr);

// 	// 维护 pid 与 connection 的关系
// 	bpf_map_update_elem(&pid_of_connection_ptr_maps, &pid, &rsi_ptr, BPF_ANY);

// 	__u64 *e = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, &pid);
// 	if (!e) {
// 		cw_bpf_debug("[Go] [uprobeThread/CreateContextStart]getget: rsi_ptr:: %llx\n", *e);
// 		return 0;
// 	}
// 	cw_bpf_debug("[Go] [uprobeThread/CreateContextStart]getget: rsi_ptr:: %llx\n", *e);
// 	// 维护 pid 与 connection 的关系

// 	return 1;
// }

// struct {
// 	__uint(type, BPF_MAP_TYPE_HASH);
// 	__uint(key_size, 14);
// 	__uint(value_size, sizeof(__u64));
// 	__uint(max_entries, 10240);
// } httpid_of_connection_ptr_maps SEC(".maps");

// SEC("uprobe/AcceptConnectionsAsync")
// int AcceptConnectionsAsync(struct pt_regs *ctx)
// {
// 	cw_bpf_debug("[Go] [uprobeThread/AcceptConnectionsAsync] enter");
// 	__u64 pid_tgid = bpf_get_current_pid_tgid();
//     __u64 pid = pid_tgid >> 32;

// 	char original[26];  
//     char final_connection_id[14];  // 13 个字符和一个结束符  

//     void *rsi_ptr = (void *)PT_REGS_PARM2(ctx);  

//     // 读取 rsi+0xc 的 26 个字符  
//     bpf_probe_read(original, sizeof(original), rsi_ptr + 0xc);  

//     // 每隔一个字符取一个字符  
//     #pragma unroll  
//     for (int i = 0; i < 13; ++i) {  
//         final_connection_id[i] = original[i * 2];  
//     }  
//     final_connection_id[13] = '\0';  // 确保字符串以null终止  

// 	cw_bpf_debug("[Go] [uprobeThread/AcceptConnectionsAsync]: rsi_ptr:: %llx\n", rsi_ptr);
// 	cw_bpf_debug("[Go] [uprobeThread/AcceptConnectionsAsync]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
// 	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][AcceptConnectionsAsync][HTTP]pid:[%d]--[%lld]--id[%s]", pid_tgid, bpf_ktime_get_ns(), final_connection_id);

// 	// 维护 pid 与 connection 的关系
// 	__u64 *e = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, &pid);
// 	if (!e) {
// 		cw_bpf_debug("[Go] [uprobeThread/AcceptConnectionsAsync] ErrorErrorError getget: rsi_ptr:: %llx\n", *e);
// 		return 0;
// 	}
// 	cw_bpf_debug("[Go] [uprobeThread/AcceptConnectionsAsync]getget: rsi_ptr:: %llx\n", *e);
// 	bpf_map_delete_elem(&pid_of_connection_ptr_maps, &pid);

// 	bpf_map_update_elem(&httpid_of_connection_ptr_maps, final_connection_id, e, BPF_ANY);

// 	__u64 *e2 = bpf_map_lookup_elem(&httpid_of_connection_ptr_maps, &final_connection_id);
// 	if (!e2) {
// 		cw_bpf_debug("[Go] [uprobeThread/AcceptConnectionsAsync] ErrorErrorError getget: rsi_ptr2:: %llx\n", *e2);
// 		return 0;
// 	}
// 	cw_bpf_debug("[Go] [uprobeThread/AcceptConnectionsAsync]getget: rsi_ptr2:: %llx\n", *e2);
// 	// 维护 pid 与 connection 的关系

// 	return 1;
// }


// SEC("uprobe/OnConnectionAsyncStart")
// int OnConnectionAsyncStart(struct pt_regs *ctx)
// {
// 	cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncStart] enter");
// 	__u64 pid_tgid = bpf_get_current_pid_tgid();
//     __u64 pid = pid_tgid >> 32;

//     char original[26];  
//     char final_connection_id[14];  // 13 个字符和一个结束符  

//     void *rsi_ptr = (void *)PT_REGS_PARM2(ctx);  

//     // 读取 rsi+0xc 的 26 个字符  
//     bpf_probe_read(original, sizeof(original), rsi_ptr + 0xc);  

//     // 每隔一个字符取一个字符  
//     #pragma unroll  
//     for (int i = 0; i < 13; ++i) {  
//         final_connection_id[i] = original[i * 2];  
//     }  
//     final_connection_id[13] = '\0';  // 确保字符串以null终止  

// 	cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncStart]: rsi_ptr:: %llx\n", rsi_ptr);
// 	cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncStart]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
// 	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][OnConnectionAsyncStart][HTTP]pid:[%d]--[%lld]--id[%s]", pid_tgid, bpf_ktime_get_ns(), final_connection_id);

// 	// 维护 pid 与 connection 的关系
// 	__u64 *e2 = bpf_map_lookup_elem(&httpid_of_connection_ptr_maps, &final_connection_id);
// 	if (!e2) {
// 		cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncStart] ErrorErrorError getget: rsi_ptr2:: %llx\n", *e2);
// 		return 0;
// 	}
// 	cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncStart]getget: rsi_ptr2:: %llx\n", *e2);

// 	bpf_map_update_elem(&pid_of_connection_ptr_maps, &pid, e2, BPF_ANY);

// 	__u64 *e3 = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, &pid);
// 	if (!e3) {
// 		cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncStart]getget: rsi_ptr3:: %llx\n", *e3);
// 		return 0;
// 	}
// 	cw_bpf_debug("[Go] [uprobeThread/OnConnectionAsyncStart]getget: rsi_ptr3:: %llx\n", *e3);
// 	// 维护 pid 与 connection 的关系
// 	return 1;
// }


// SEC("uprobe/DoSendStart")
// int DoSendStart(struct pt_regs *ctx)
// {
// 	cw_bpf_debug("[Go] [uprobeThread/DoSendStart] enter");
// 	__u64 pid_tgid = bpf_get_current_pid_tgid();
//     __u64 pid = pid_tgid >> 32;
	

// 	void *rdi_ptr = (void *)PT_REGS_PARM1(ctx);

// 	void* fd_ptr;
//     if (bpf_probe_read(&fd_ptr, sizeof(fd_ptr), rdi_ptr - 0xe8 + 0x28)) {
//         // return 1;
//     }
// 	cw_bpf_debug("[Go] [uprobeThread/DoSendStart]: fd_ptr: %llx\n", fd_ptr);
// 	void* fd_ptr2;
//     if (bpf_probe_read(&fd_ptr2, sizeof(fd_ptr2), fd_ptr + 0x28)) {
//         // return 1;
//     }

// 	cw_bpf_debug("[Go] [uprobeThread/DoSendStart]: rsi_ptr:: %llx\n", fd_ptr2);

// 	char original[26];  
//     char final_connection_id[14];  // 13 个字符和一个结束符 

// 	// 读取 rsi+0xc 的 26 个字符  
//     bpf_probe_read(original, sizeof(original), fd_ptr2 + 0xc);  

//     // 每隔一个字符取一个字符  
//     #pragma unroll  
//     for (int i = 0; i < 13; ++i) {  
//         final_connection_id[i] = original[i * 2];  
//     }  
//     final_connection_id[13] = '\0';  // 确保字符串以null终止  

// 	cw_bpf_debug("[Go] [uprobeThread/DoSendStart]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
// 	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][DoSendStart][HTTP]pid:[%d]--[%lld]--id[%s]", pid_tgid, bpf_ktime_get_ns(), final_connection_id);

// 	// 维护 pid 与 connection 的关系
// 	__u64 *e2 = bpf_map_lookup_elem(&httpid_of_connection_ptr_maps, &final_connection_id);
// 	if (!e2) {
// 		cw_bpf_debug("[Go] [uprobeThread/DoSendStart] ErrorErrorError getget: rsi_ptr2:: %llx\n", *e2);
// 		return 0;
// 	}
// 	cw_bpf_debug("[Go] [uprobeThread/DoSendStart]getget: rsi_ptr2:: %llx\n", *e2);

// 	bpf_map_update_elem(&pid_of_connection_ptr_maps, &pid, e2, BPF_ANY);

// 	__u64 *e3 = bpf_map_lookup_elem(&pid_of_connection_ptr_maps, &pid);
// 	if (!e3) {
// 		cw_bpf_debug("[Go] [uprobeThread/DoSendStart] ErrorErrorError getget: rsi_ptr3:: %llx\n", *e3);
// 		return 0;
// 	}
// 	cw_bpf_debug("[Go] [uprobeThread/DoSendStart]getget: rsi_ptr3:: %llx\n", *e3);
// 	// 维护 pid 与 connection 的关系


// 	// 维护函数出入口，用于关闭 当前 Connection 与线程的关系
// 	__u64 ip = PT_REGS_IP(ctx);
// 	__u64 asm_;
// 	bpf_probe_read_user(&asm_, sizeof(asm_), (void*)ip);

// 	asm_ = asm_ >> 32;
// 	cw_bpf_debug("[Go] [uprobeThread/DoSendStart/ent]: e->asm: %x", asm_);

// 	__u64 bp = PT_REGS_SP(ctx);
// 	// __u64 bp = PT_REGS_SP(ctx) + asm_;
// 	__u64 caller_bp = PT_REGS_FP(ctx);

// 	struct trace_stack_entry_key_t trace_key = {};
// 	trace_key.caller_bp = caller_bp;
// 	trace_key.bp = bp;
// 	trace_key.trace_id = 0;

// 	cw_bpf_debug("[Go] [uprobeThread/DoSendStart/ent]: trace_keytrace_keytrace_key: rbp: %x, rbp: %x, rip:%x", PT_REGS_FP(ctx), PT_REGS_SP(ctx), PT_REGS_IP(ctx));
// 	cw_bpf_debug("[Go] [uprobeThread/DoSendStart/ent]: trace_keytrace_keytrace_key: caller_bp: %x, bp: %x", trace_key.caller_bp, trace_key.bp);

// 	bpf_map_update_elem(&trace_stack_entry_thread, &trace_key, &pid, BPF_ANY);
// 	// 维护函数出入口，用于关闭 当前 Connection 与线程的关系

// 	return 1;
// }



// 后面 hook 暂时主流程中用不到，主要在调试过程中使用

// SEC("uprobe/DoReceiveStart")
// int DoReceiveStart(struct pt_regs *ctx)
// {
// 	cw_bpf_debug("[Go] [uprobeThread/DoReceiveStart] enter");
// 	__u64 pid_tgid = bpf_get_current_pid_tgid();
//     __u64 pid = pid_tgid >> 32;

// 	void *rdi_ptr = (void *)PT_REGS_PARM1(ctx);

// 	void* fd_ptr;
//     if (bpf_probe_read(&fd_ptr, sizeof(fd_ptr), rdi_ptr + 0x28)) {
//         // return 1;
//     }
// 	cw_bpf_debug("[Go] [uprobeThread/DoReceiveStart]: fd_ptr: %llx\n", fd_ptr);
// 	void* fd_ptr2;
//     if (bpf_probe_read(&fd_ptr2, sizeof(fd_ptr2), fd_ptr + 0x28)) {
//         // return 1;
//     }

// 	cw_bpf_debug("[Go] [uprobeThread/DoReceiveStart]: rsi_ptr:: %llx\n", fd_ptr2);

// 	char original[26];  
//     char final_connection_id[14];  // 13 个字符和一个结束符 

// 	// 读取 rsi+0xc 的 26 个字符  
//     bpf_probe_read(original, sizeof(original), fd_ptr2 + 0xc);  

//     // 每隔一个字符取一个字符  
//     #pragma unroll  
//     for (int i = 0; i < 13; ++i) {  
//         final_connection_id[i] = original[i * 2];  
//     }  
//     final_connection_id[13] = '\0';  // 确保字符串以null终止  
	
// 	cw_bpf_debug("[Go] [uprobeThread/DoReceiveStart]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
// 	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][DoReceiveStart][HTTP]pid:[%d]--[%lld]--id[%s]", pid_tgid, bpf_ktime_get_ns(), final_connection_id);

// 	return 1;
// }

// SEC("uprobe/DoReceiveEnd")
// int DoReceiveEnd(struct pt_regs *ctx)
// {
// 	cw_bpf_debug("[Go] [uprobeThread/DoReceiveEnd] enter");
// 	__u64 pid_tgid = bpf_get_current_pid_tgid();
//     __u64 pid = pid_tgid >> 32;

// 	cw_bpf_debug("[Go] [uprobeThread/DoReceiveEnd]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
// 	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][DoReceiveEnd][HTTP]pid:[%d]--[%lld]", pid_tgid, bpf_ktime_get_ns());

// 	return 1;
// }

// SEC("uprobe/ReceiveStart")
// int ReceiveStart(struct pt_regs *ctx)
// {
// 	cw_bpf_debug("[Go] [uprobeThread/ReceiveStart] enter");
// 	__u64 pid_tgid = bpf_get_current_pid_tgid();
//     __u64 pid = pid_tgid >> 32;

// 	cw_bpf_debug("[Go] [uprobeThread/ReceiveStart]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
// 	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][ReceiveStart][HTTP]pid:[%d]--[%lld]", pid_tgid, bpf_ktime_get_ns());

// 	return 1;
// }

// SEC("uprobe/ReceiveEnd")
// int ReceiveEnd(struct pt_regs *ctx)
// {
// 	cw_bpf_debug("[Go] [uprobeThread/ReceiveEnd] enter");
// 	__u64 pid_tgid = bpf_get_current_pid_tgid();
//     __u64 pid = pid_tgid >> 32;

// 	cw_bpf_debug("[Go] [uprobeThread/ReceiveEnd]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
// 	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][ReceiveEnd][HTTP]pid:[%d]--[%lld]", pid_tgid, bpf_ktime_get_ns());

// 	return 1;
// }

// SEC("uprobe/SendStart")
// int SendStart(struct pt_regs *ctx)
// {
// 	cw_bpf_debug("[Go] [uprobeThread/SendStart] enter");
// 	__u64 pid_tgid = bpf_get_current_pid_tgid();
//     __u64 pid = pid_tgid >> 32;

// 	cw_bpf_debug("[Go] [uprobeThread/SendStart]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
// 	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][SendStart][HTTP]pid:[%d]--[%lld]", pid_tgid, bpf_ktime_get_ns());

// 	return 1;
// }

// SEC("uprobe/SendEnd")
// int SendEnd(struct pt_regs *ctx)
// {
// 	cw_bpf_debug("[Go] [uprobeThread/SendEnd] enter");
// 	__u64 pid_tgid = bpf_get_current_pid_tgid();
//     __u64 pid = pid_tgid >> 32;

// 	cw_bpf_debug("[Go] [uprobeThread/SendEnd]: get_apm_trace_id:: %d, %d\n", pid, pid_tgid);
// 	cw_bpf_debug("[Go] [uprobeThread/pidpidpidpid][SendEnd][HTTP]pid:[%d]--[%lld]", pid_tgid, bpf_ktime_get_ns());

// 	return 1;
// }
