diff --git a/bpf/go_common.h b/bpf/go_common.h index d8cf269e2..f440a7fd0 100644 --- a/bpf/go_common.h +++ b/bpf/go_common.h @@ -32,14 +32,19 @@ char __license[] SEC("license") = "Dual MIT/GPL"; // Then it is retrieved in the return uprobes and used to know the HTTP call duration as well as its // attributes (method, path, and status code). +typedef struct goroutine_key { + u64 pid; // PID of the process + u64 addr; // Address of the goroutine +} goroutine_key_t; + typedef struct goroutine_metadata_t { - u64 parent; + goroutine_key_t parent; u64 timestamp; } goroutine_metadata; struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: pointer to the goroutine + __type(key, goroutine_key_t); // key: pointer to the goroutine __type(value, goroutine_metadata); // value: timestamp of the goroutine creation __uint(max_entries, MAX_CONCURRENT_SHARED_REQUESTS); __uint(pinning, LIBBPF_PIN_BY_NAME); @@ -47,7 +52,7 @@ struct { struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: pointer to the request goroutine + __type(key, goroutine_key_t); // key: pointer to the request goroutine __type(value, connection_info_t); __uint(max_entries, MAX_CONCURRENT_SHARED_REQUESTS); __uint(pinning, LIBBPF_PIN_BY_NAME); @@ -55,37 +60,52 @@ struct { struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: pointer to the request goroutine + __type(key, goroutine_key_t); // key: pointer to the request goroutine __type(value, connection_info_t); __uint(max_entries, MAX_CONCURRENT_REQUESTS); } ongoing_client_connections SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: pointer to the goroutine - __type(value, tp_info_t); // value: traceparent info + __type(key, goroutine_key_t); // key: pointer to the goroutine + __type(value, tp_info_t); // value: traceparent info __uint(max_entries, MAX_CONCURRENT_SHARED_REQUESTS); __uint(pinning, LIBBPF_PIN_BY_NAME); } go_trace_map SEC(".maps"); -static __always_inline u64 find_parent_goroutine(void *goroutine_addr) { - void *r_addr = goroutine_addr; +static __always_inline void goroutine_key_from_id(goroutine_key_t *current, void *goroutine) { + u64 pid_tid = bpf_get_current_pid_tgid(); + u32 pid = pid_from_pid_tgid(pid_tid); + + current->addr = (u64)goroutine; + current->pid = pid; +} + +static __always_inline u64 find_parent_goroutine(goroutine_key_t *current) { + if (!current) { + return 0; + } + + u64 r_addr = current->addr; + goroutine_key_t *parent = current; + int attempts = 0; do { - void *p_inv = bpf_map_lookup_elem(&go_trace_map, &r_addr); + tp_info_t *p_inv = bpf_map_lookup_elem(&go_trace_map, parent); if (!p_inv) { // not this goroutine running the server request processing // Let's find the parent scope goroutine_metadata *g_metadata = - (goroutine_metadata *)bpf_map_lookup_elem(&ongoing_goroutines, &r_addr); + (goroutine_metadata *)bpf_map_lookup_elem(&ongoing_goroutines, parent); if (g_metadata) { // Lookup now to see if the parent was a request - r_addr = (void *)g_metadata->parent; + r_addr = g_metadata->parent.addr; + parent = &g_metadata->parent; } else { break; } } else { bpf_dbg_printk("Found parent %lx", r_addr); - return (u64)r_addr; + return r_addr; } attempts++; @@ -131,6 +151,8 @@ server_trace_parent(void *goroutine_addr, tp_info_t *tp, void *req_header) { tp->flags = 1; // Get traceparent from the Request.Header void *traceparent_ptr = extract_traceparent_from_req_headers(req_header); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); if (traceparent_ptr != NULL) { unsigned char buf[TP_MAX_VAL_LENGTH]; long res = bpf_probe_read(buf, sizeof(buf), traceparent_ptr); @@ -143,7 +165,7 @@ server_trace_parent(void *goroutine_addr, tp_info_t *tp, void *req_header) { decode_go_traceparent(buf, tp->trace_id, tp->parent_id, &tp->flags); } } else { - connection_info_t *info = bpf_map_lookup_elem(&ongoing_server_connections, &goroutine_addr); + connection_info_t *info = bpf_map_lookup_elem(&ongoing_server_connections, &g_key); u8 found_info = 0; if (info) { @@ -169,7 +191,7 @@ server_trace_parent(void *goroutine_addr, tp_info_t *tp, void *req_header) { } urand_bytes(tp->span_id, SPAN_ID_SIZE_BYTES); - bpf_map_update_elem(&go_trace_map, &goroutine_addr, tp, BPF_ANY); + bpf_map_update_elem(&go_trace_map, &g_key, tp, BPF_ANY); unsigned char tp_buf[TP_MAX_VAL_LENGTH]; make_tp_string(tp_buf, tp); @@ -201,11 +223,15 @@ static __always_inline u8 client_trace_parent(void *goroutine_addr, if (!found_trace_id) { tp_info_t *tp = 0; + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); - u64 parent_id = find_parent_goroutine(goroutine_addr); + u64 parent_id = find_parent_goroutine(&g_key); + goroutine_key_t p_key = {}; + goroutine_key_from_id(&p_key, (void *)parent_id); if (parent_id) { // we found a parent request - tp = (tp_info_t *)bpf_map_lookup_elem(&go_trace_map, &parent_id); + tp = (tp_info_t *)bpf_map_lookup_elem(&go_trace_map, &p_key); } if (tp) { diff --git a/bpf/go_grpc.h b/bpf/go_grpc.h index e360d8dd1..8d3269792 100644 --- a/bpf/go_grpc.h +++ b/bpf/go_grpc.h @@ -28,7 +28,7 @@ typedef struct grpc_srv_func_invocation { struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: pointer to the request goroutine + __type(key, goroutine_key_t); // key: pointer to the request goroutine __type(value, u16); __uint(max_entries, MAX_CONCURRENT_REQUESTS); } ongoing_grpc_request_status SEC(".maps"); @@ -56,21 +56,21 @@ struct { struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: goroutine - __type(value, void *); // the transport * + __type(key, goroutine_key_t); // key: goroutine + __type(value, void *); // the transport * __uint(max_entries, MAX_CONCURRENT_REQUESTS); } ongoing_grpc_operate_headers SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: pointer to the request goroutine + __type(key, goroutine_key_t); // key: pointer to the request goroutine __type(value, grpc_client_func_invocation_t); __uint(max_entries, MAX_CONCURRENT_REQUESTS); } ongoing_grpc_client_requests SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: pointer to the request goroutine + __type(key, goroutine_key_t); // key: pointer to the request goroutine __type(value, grpc_srv_func_invocation_t); __uint(max_entries, MAX_CONCURRENT_REQUESTS); } ongoing_grpc_server_requests SEC(".maps"); @@ -101,6 +101,8 @@ int uprobe_server_handleStream(struct pt_regs *ctx) { bpf_dbg_printk("=== uprobe/server_handleStream === "); void *goroutine_addr = GOROUTINE_PTR(ctx); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); void *stream_ptr = GO_PARAM4(ctx); off_table_t *ot = get_offsets_table(); @@ -129,7 +131,7 @@ int uprobe_server_handleStream(struct pt_regs *ctx) { } } - if (bpf_map_update_elem(&ongoing_grpc_server_requests, &goroutine_addr, &invocation, BPF_ANY)) { + if (bpf_map_update_elem(&ongoing_grpc_server_requests, &g_key, &invocation, BPF_ANY)) { bpf_dbg_printk("can't update grpc map element"); } @@ -141,8 +143,10 @@ SEC("uprobe/netFdReadGRPC") int uprobe_netFdReadGRPC(struct pt_regs *ctx) { void *goroutine_addr = GOROUTINE_PTR(ctx); bpf_dbg_printk("=== uprobe/proc netFD read goroutine %lx === ", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); - void *tr = bpf_map_lookup_elem(&ongoing_grpc_operate_headers, &goroutine_addr); + void *tr = bpf_map_lookup_elem(&ongoing_grpc_operate_headers, &g_key); bpf_dbg_printk("tr %llx", tr); if (tr) { grpc_transports_t *t = bpf_map_lookup_elem(&ongoing_grpc_transports, tr); @@ -163,13 +167,15 @@ int uprobe_http2Server_operateHeaders(struct pt_regs *ctx) { void *tr = GO_PARAM1(ctx); bpf_dbg_printk( "=== uprobe/http2Server_operateHeaders tr %llx goroutine %lx === ", tr, goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); grpc_transports_t t = { .type = TRANSPORT_HTTP2, .conn = {0}, }; - bpf_map_update_elem(&ongoing_grpc_operate_headers, &goroutine_addr, &tr, BPF_ANY); + bpf_map_update_elem(&ongoing_grpc_operate_headers, &g_key, &tr, BPF_ANY); bpf_map_update_elem(&ongoing_grpc_transports, &tr, &t, BPF_ANY); return 0; @@ -184,10 +190,15 @@ int uprobe_server_handler_transport_handle_streams(struct pt_regs *ctx) { tr, goroutine_addr); - void *parent_go = (void *)find_parent_goroutine(goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); + + void *parent_go = (void *)find_parent_goroutine(&g_key); if (parent_go) { bpf_dbg_printk("found parent goroutine for transport handler [%llx]", parent_go); - connection_info_t *conn = bpf_map_lookup_elem(&ongoing_server_connections, &parent_go); + goroutine_key_t p_key = {}; + goroutine_key_from_id(&p_key, parent_go); + connection_info_t *conn = bpf_map_lookup_elem(&ongoing_server_connections, &p_key); bpf_dbg_printk("conn %llx", conn); if (conn) { grpc_transports_t t = { @@ -210,15 +221,17 @@ int uprobe_server_handleStream_return(struct pt_regs *ctx) { off_table_t *ot = get_offsets_table(); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); grpc_srv_func_invocation_t *invocation = - bpf_map_lookup_elem(&ongoing_grpc_server_requests, &goroutine_addr); + bpf_map_lookup_elem(&ongoing_grpc_server_requests, &g_key); if (invocation == NULL) { bpf_dbg_printk("can't read grpc invocation metadata"); goto done; } - u16 *status_ptr = bpf_map_lookup_elem(&ongoing_grpc_request_status, &goroutine_addr); + u16 *status_ptr = bpf_map_lookup_elem(&ongoing_grpc_request_status, &g_key); u16 status = 0; if (status_ptr != NULL) { bpf_dbg_printk("can't read grpc invocation status"); @@ -242,10 +255,10 @@ int uprobe_server_handleStream_return(struct pt_regs *ctx) { trace->content_length = 0; trace->method[0] = 0; - goroutine_metadata *g_metadata = bpf_map_lookup_elem(&ongoing_goroutines, &goroutine_addr); + goroutine_metadata *g_metadata = bpf_map_lookup_elem(&ongoing_goroutines, &g_key); if (g_metadata) { trace->go_start_monotime_ns = g_metadata->timestamp; - bpf_map_delete_elem(&ongoing_goroutines, &goroutine_addr); + bpf_map_delete_elem(&ongoing_goroutines, &g_key); } else { trace->go_start_monotime_ns = invocation->start_monotime_ns; } @@ -295,9 +308,9 @@ int uprobe_server_handleStream_return(struct pt_regs *ctx) { bpf_ringbuf_submit(trace, get_flags()); done: - bpf_map_delete_elem(&ongoing_grpc_server_requests, &goroutine_addr); - bpf_map_delete_elem(&ongoing_grpc_request_status, &goroutine_addr); - bpf_map_delete_elem(&go_trace_map, &goroutine_addr); + bpf_map_delete_elem(&ongoing_grpc_server_requests, &g_key); + bpf_map_delete_elem(&ongoing_grpc_request_status, &g_key); + bpf_map_delete_elem(&go_trace_map, &g_key); return 0; } @@ -310,6 +323,8 @@ int uprobe_transport_writeStatus(struct pt_regs *ctx) { off_table_t *ot = get_offsets_table(); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); void *status_ptr = GO_PARAM3(ctx); bpf_dbg_printk("status_ptr %lx", status_ptr); @@ -330,7 +345,7 @@ int uprobe_transport_writeStatus(struct pt_regs *ctx) { sizeof(status), (void *)(s_ptr + go_offset_of(ot, (go_offset){.v = _grpc_status_code_ptr_pos}))); bpf_dbg_printk("status code %d", status); - bpf_map_update_elem(&ongoing_grpc_request_status, &goroutine_addr, &status, BPF_ANY); + bpf_map_update_elem(&ongoing_grpc_request_status, &g_key, &status, BPF_ANY); } } @@ -349,6 +364,8 @@ static __always_inline void clientConnStart( .flags = 0, }; off_table_t *ot = get_offsets_table(); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); if (ctx_ptr) { void *val_ptr = 0; @@ -366,7 +383,7 @@ static __always_inline void clientConnStart( } // Write event - if (bpf_map_update_elem(&ongoing_grpc_client_requests, &goroutine_addr, &invocation, BPF_ANY)) { + if (bpf_map_update_elem(&ongoing_grpc_client_requests, &g_key, &invocation, BPF_ANY)) { bpf_dbg_printk("can't update grpc client map element"); } } @@ -409,9 +426,11 @@ int uprobe_ClientConn_NewStream(struct pt_regs *ctx) { static __always_inline int grpc_connect_done(struct pt_regs *ctx, void *err) { void *goroutine_addr = GOROUTINE_PTR(ctx); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); grpc_client_func_invocation_t *invocation = - bpf_map_lookup_elem(&ongoing_grpc_client_requests, &goroutine_addr); + bpf_map_lookup_elem(&ongoing_grpc_client_requests, &g_key); if (invocation == NULL) { bpf_dbg_printk("can't read grpc client invocation metadata"); @@ -447,7 +466,7 @@ static __always_inline int grpc_connect_done(struct pt_regs *ctx, void *err) { goto done; } - connection_info_t *info = bpf_map_lookup_elem(&ongoing_client_connections, &goroutine_addr); + connection_info_t *info = bpf_map_lookup_elem(&ongoing_client_connections, &g_key); if (info) { __builtin_memcpy(&trace->conn, info, sizeof(connection_info_t)); @@ -466,7 +485,7 @@ static __always_inline int grpc_connect_done(struct pt_regs *ctx, void *err) { bpf_ringbuf_submit(trace, get_flags()); done: - bpf_map_delete_elem(&ongoing_grpc_client_requests, &goroutine_addr); + bpf_map_delete_elem(&ongoing_grpc_client_requests, &g_key); return 0; } @@ -490,8 +509,10 @@ int uprobe_ClientConn_Close(struct pt_regs *ctx) { void *goroutine_addr = GOROUTINE_PTR(ctx); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); - bpf_map_delete_elem(&ongoing_grpc_client_requests, &goroutine_addr); + bpf_map_delete_elem(&ongoing_grpc_client_requests, &g_key); return 0; } @@ -526,6 +547,8 @@ int uprobe_transport_http2Client_NewStream(struct pt_regs *ctx) { void *goroutine_addr = GOROUTINE_PTR(ctx); void *t_ptr = GO_PARAM1(ctx); off_table_t *ot = get_offsets_table(); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); u64 grpc_t_conn_pos = go_offset_of(ot, (go_offset){.v = _grpc_t_scheme_pos}); bpf_dbg_printk( @@ -561,8 +584,7 @@ int uprobe_transport_http2Client_NewStream(struct pt_regs *ctx) { connection_info_t conn = {0}; u8 ok = get_conn_info(conn_conn_ptr, &conn); if (ok) { - bpf_map_update_elem( - &ongoing_client_connections, &goroutine_addr, &conn, BPF_ANY); + bpf_map_update_elem(&ongoing_client_connections, &g_key, &conn, BPF_ANY); } } } @@ -578,7 +600,7 @@ int uprobe_transport_http2Client_NewStream(struct pt_regs *ctx) { bpf_dbg_printk("next_id %d", next_id); grpc_client_func_invocation_t *invocation = - bpf_map_lookup_elem(&ongoing_grpc_client_requests, &goroutine_addr); + bpf_map_lookup_elem(&ongoing_grpc_client_requests, &g_key); if (invocation) { grpc_client_func_invocation_t inv_save = *invocation; @@ -605,7 +627,7 @@ typedef struct grpc_framer_func_invocation { struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: go routine doing framer write headers + __type(key, goroutine_key_t); // key: go routine doing framer write headers __type( value, grpc_framer_func_invocation_t); // the goroutine of the round trip request, which is the key for our traceparent info @@ -638,6 +660,8 @@ int uprobe_grpcFramerWriteHeaders(struct pt_regs *ctx) { if (invocation) { bpf_dbg_printk("Found invocation info %llx", invocation); void *goroutine_addr = GOROUTINE_PTR(ctx); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); void *w_ptr = (void *)(framer + framer_w_pos + 16); bpf_probe_read(&w_ptr, sizeof(w_ptr), (void *)(framer + framer_w_pos + 8)); @@ -662,7 +686,7 @@ int uprobe_grpcFramerWriteHeaders(struct pt_regs *ctx) { .offset = offset, }; - bpf_map_update_elem(&grpc_framer_invocation_map, &goroutine_addr, &f_info, BPF_ANY); + bpf_map_update_elem(&grpc_framer_invocation_map, &g_key, &f_info, BPF_ANY); } else { bpf_dbg_printk("Offset too large, ignoring..."); } @@ -689,9 +713,11 @@ int uprobe_grpcFramerWriteHeaders_returns(struct pt_regs *ctx) { void *goroutine_addr = GOROUTINE_PTR(ctx); off_table_t *ot = get_offsets_table(); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); grpc_framer_func_invocation_t *f_info = - bpf_map_lookup_elem(&grpc_framer_invocation_map, &goroutine_addr); + bpf_map_lookup_elem(&grpc_framer_invocation_map, &g_key); if (f_info) { void *w_ptr = @@ -792,7 +818,7 @@ int uprobe_grpcFramerWriteHeaders_returns(struct pt_regs *ctx) { } } - bpf_map_delete_elem(&grpc_framer_invocation_map, &goroutine_addr); + bpf_map_delete_elem(&grpc_framer_invocation_map, &g_key); return 0; } #else diff --git a/bpf/go_kafka_go.h b/bpf/go_kafka_go.h index 7661e158f..2cbbc30d2 100644 --- a/bpf/go_kafka_go.h +++ b/bpf/go_kafka_go.h @@ -36,8 +36,8 @@ struct { struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // goroutine - __type(value, topic_t); // topic info + __type(key, goroutine_key_t); // goroutine + __type(value, topic_t); // topic info __uint(max_entries, MAX_CONCURRENT_REQUESTS); } ongoing_produce_topics SEC(".maps"); @@ -50,14 +50,14 @@ struct { struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // goroutine + __type(key, goroutine_key_t); // goroutine __type(value, produce_req_t); // rw ptr + start time __uint(max_entries, MAX_CONCURRENT_REQUESTS); } produce_requests SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // goroutine + __type(key, goroutine_key_t); // goroutine __type(value, kafka_go_req_t); // rw ptr + start time __uint(max_entries, MAX_CONCURRENT_REQUESTS); } fetch_requests SEC(".maps"); @@ -83,6 +83,8 @@ SEC("uprobe/writer_produce") int uprobe_writer_produce(struct pt_regs *ctx) { void *goroutine_addr = (void *)GOROUTINE_PTR(ctx); bpf_dbg_printk("=== uprobe/kafka-go writer_produce %llx === ", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); void *w_ptr = (void *)GO_PARAM1(ctx); off_table_t *ot = get_offsets_table(); @@ -107,7 +109,7 @@ int uprobe_writer_produce(struct pt_regs *ctx) { } bpf_probe_read_user(&topic.name, sizeof(topic.name), topic_ptr); - bpf_map_update_elem(&ongoing_produce_topics, &goroutine_addr, &topic, BPF_ANY); + bpf_map_update_elem(&ongoing_produce_topics, &g_key, &topic, BPF_ANY); } bpf_map_delete_elem(&produce_traceparents, &w_ptr); } @@ -119,8 +121,10 @@ SEC("uprobe/client_roundTrip") int uprobe_client_roundTrip(struct pt_regs *ctx) { void *goroutine_addr = (void *)GOROUTINE_PTR(ctx); bpf_dbg_printk("=== uprobe/kafka-go client_roundTrip %llx === ", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); - topic_t *topic_ptr = bpf_map_lookup_elem(&ongoing_produce_topics, &goroutine_addr); + topic_t *topic_ptr = bpf_map_lookup_elem(&ongoing_produce_topics, &g_key); if (topic_ptr) { void *msg_ptr = (void *)GO_PARAM7(ctx); @@ -132,7 +136,7 @@ int uprobe_client_roundTrip(struct pt_regs *ctx) { } } - bpf_map_delete_elem(&ongoing_produce_topics, &goroutine_addr); + bpf_map_delete_elem(&ongoing_produce_topics, &g_key); return 0; } @@ -146,6 +150,8 @@ int uprobe_protocol_roundtrip(struct pt_regs *ctx) { bpf_dbg_printk( "goroutine_addr %lx, rw ptr %llx, msg_ptr %llx", goroutine_addr, rw_ptr, msg_ptr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); if (rw_ptr) { topic_t *topic_ptr = bpf_map_lookup_elem(&ongoing_produce_messages, &msg_ptr); @@ -158,7 +164,7 @@ int uprobe_protocol_roundtrip(struct pt_regs *ctx) { .start_monotime_ns = bpf_ktime_get_ns(), }; - bpf_map_update_elem(&produce_requests, &goroutine_addr, &p, BPF_ANY); + bpf_map_update_elem(&produce_requests, &g_key, &p, BPF_ANY); } } @@ -169,8 +175,10 @@ SEC("uprobe/protocol_RoundTrip_ret") int uprobe_protocol_roundtrip_ret(struct pt_regs *ctx) { void *goroutine_addr = (void *)GOROUTINE_PTR(ctx); bpf_dbg_printk("=== uprobe/protocol_RoundTrip ret %llx === ", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); - produce_req_t *p_ptr = bpf_map_lookup_elem(&produce_requests, &goroutine_addr); + produce_req_t *p_ptr = bpf_map_lookup_elem(&produce_requests, &g_key); bpf_dbg_printk("p_ptr %llx", p_ptr); @@ -209,7 +217,7 @@ int uprobe_protocol_roundtrip_ret(struct pt_regs *ctx) { bpf_map_delete_elem(&ongoing_produce_messages, &msg_ptr); } - bpf_map_delete_elem(&produce_requests, &goroutine_addr); + bpf_map_delete_elem(&produce_requests, &g_key); return 0; } @@ -223,6 +231,8 @@ int uprobe_reader_read(struct pt_regs *ctx) { off_table_t *ot = get_offsets_table(); bpf_dbg_printk("=== uprobe/kafka-go reader_read %llx r_ptr %llx=== ", goroutine_addr, r_ptr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); if (r_ptr) { kafka_go_req_t r = { @@ -253,7 +263,7 @@ int uprobe_reader_read(struct pt_regs *ctx) { } } - bpf_map_update_elem(&fetch_requests, &goroutine_addr, &r, BPF_ANY); + bpf_map_update_elem(&fetch_requests, &g_key, &r, BPF_ANY); } return 0; @@ -263,8 +273,10 @@ SEC("uprobe/reader_send_message") int uprobe_reader_send_message(struct pt_regs *ctx) { void *goroutine_addr = (void *)GOROUTINE_PTR(ctx); bpf_dbg_printk("=== uprobe/kafka-go reader_send_message %llx === ", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); - kafka_go_req_t *req = (kafka_go_req_t *)bpf_map_lookup_elem(&fetch_requests, &goroutine_addr); + kafka_go_req_t *req = (kafka_go_req_t *)bpf_map_lookup_elem(&fetch_requests, &g_key); bpf_dbg_printk("Found req_ptr %llx", req); if (req) { @@ -278,8 +290,10 @@ SEC("uprobe/reader_read") int uprobe_reader_read_ret(struct pt_regs *ctx) { void *goroutine_addr = (void *)GOROUTINE_PTR(ctx); bpf_dbg_printk("=== uprobe/kafka-go reader_read ret %llx === ", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); - kafka_go_req_t *req = (kafka_go_req_t *)bpf_map_lookup_elem(&fetch_requests, &goroutine_addr); + kafka_go_req_t *req = (kafka_go_req_t *)bpf_map_lookup_elem(&fetch_requests, &g_key); bpf_dbg_printk("Found req_ptr %llx", req); if (req) { @@ -296,7 +310,7 @@ int uprobe_reader_read_ret(struct pt_regs *ctx) { } } - bpf_map_delete_elem(&fetch_requests, &goroutine_addr); + bpf_map_delete_elem(&fetch_requests, &g_key); return 0; } \ No newline at end of file diff --git a/bpf/go_nethttp.h b/bpf/go_nethttp.h index 61df05e76..e7e08db37 100644 --- a/bpf/go_nethttp.h +++ b/bpf/go_nethttp.h @@ -40,14 +40,14 @@ typedef struct http_client_data { struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: pointer to the request goroutine + __type(key, goroutine_key_t); // key: pointer to the request goroutine __type(value, http_func_invocation_t); __uint(max_entries, MAX_CONCURRENT_REQUESTS); } ongoing_http_client_requests SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: pointer to the request goroutine + __type(key, goroutine_key_t); // key: pointer to the request goroutine __type(value, http_client_data_t); __uint(max_entries, MAX_CONCURRENT_REQUESTS); } ongoing_http_client_requests_data SEC(".maps"); @@ -64,7 +64,7 @@ typedef struct server_http_func_invocation { struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: pointer to the request goroutine + __type(key, goroutine_key_t); // key: pointer to the request goroutine __type(value, server_http_func_invocation_t); __uint(max_entries, MAX_CONCURRENT_REQUESTS); } ongoing_http_server_requests SEC(".maps"); @@ -81,6 +81,8 @@ int uprobe_ServeHTTP(struct pt_regs *ctx) { bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); void *req = GO_PARAM4(ctx); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); off_table_t *ot = get_offsets_table(); @@ -143,7 +145,7 @@ int uprobe_ServeHTTP(struct pt_regs *ctx) { } // Write event - if (bpf_map_update_elem(&ongoing_http_server_requests, &goroutine_addr, &invocation, BPF_ANY)) { + if (bpf_map_update_elem(&ongoing_http_server_requests, &g_key, &invocation, BPF_ANY)) { bpf_dbg_printk("can't update map element"); } @@ -159,8 +161,10 @@ int uprobe_readRequestStart(struct pt_regs *ctx) { off_table_t *ot = get_offsets_table(); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); - connection_info_t *existing = bpf_map_lookup_elem(&ongoing_server_connections, &goroutine_addr); + connection_info_t *existing = bpf_map_lookup_elem(&ongoing_server_connections, &g_key); if (!existing) { void *c_ptr = GO_PARAM1(ctx); @@ -186,8 +190,7 @@ int uprobe_readRequestStart(struct pt_regs *ctx) { get_conn_info( conn_ptr, &conn); // initialized to 0, no need to check the result if we succeeded - bpf_map_update_elem( - &ongoing_server_connections, &goroutine_addr, &conn, BPF_ANY); + bpf_map_update_elem(&ongoing_server_connections, &g_key, &conn, BPF_ANY); } } } @@ -203,16 +206,19 @@ int uprobe_readRequestReturns(struct pt_regs *ctx) { void *goroutine_addr = GOROUTINE_PTR(ctx); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); + // This code is here for keepalive support on HTTP requests. Since the connection is not // established everytime, we set the initial goroutine start on the new read initiation. - goroutine_metadata *g_metadata = bpf_map_lookup_elem(&ongoing_goroutines, &goroutine_addr); + goroutine_metadata *g_metadata = bpf_map_lookup_elem(&ongoing_goroutines, &g_key); if (!g_metadata) { goroutine_metadata metadata = { .timestamp = bpf_ktime_get_ns(), - .parent = (u64)goroutine_addr, + .parent = g_key, }; - if (bpf_map_update_elem(&ongoing_goroutines, &goroutine_addr, &metadata, BPF_ANY)) { + if (bpf_map_update_elem(&ongoing_goroutines, &g_key, &metadata, BPF_ANY)) { bpf_dbg_printk("can't update active goroutine"); } } @@ -226,16 +232,21 @@ int uprobe_ServeHTTPReturns(struct pt_regs *ctx) { void *goroutine_addr = GOROUTINE_PTR(ctx); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); server_http_func_invocation_t *invocation = - bpf_map_lookup_elem(&ongoing_http_server_requests, &goroutine_addr); + bpf_map_lookup_elem(&ongoing_http_server_requests, &g_key); if (invocation == NULL) { - void *parent_go = (void *)find_parent_goroutine(goroutine_addr); + void *parent_go = (void *)find_parent_goroutine(&g_key); if (parent_go) { bpf_dbg_printk("found parent goroutine for header [%llx]", parent_go); - invocation = bpf_map_lookup_elem(&ongoing_http_server_requests, &parent_go); + goroutine_key_t p_key = {}; + goroutine_key_from_id(&p_key, parent_go); + invocation = bpf_map_lookup_elem(&ongoing_http_server_requests, &p_key); goroutine_addr = parent_go; + g_key.addr = (u64)goroutine_addr; } if (!invocation) { bpf_dbg_printk("can't read http invocation metadata"); @@ -258,15 +269,15 @@ int uprobe_ServeHTTPReturns(struct pt_regs *ctx) { trace->start_monotime_ns = invocation->start_monotime_ns; trace->end_monotime_ns = bpf_ktime_get_ns(); - goroutine_metadata *g_metadata = bpf_map_lookup_elem(&ongoing_goroutines, &goroutine_addr); + goroutine_metadata *g_metadata = bpf_map_lookup_elem(&ongoing_goroutines, &g_key); if (g_metadata) { trace->go_start_monotime_ns = g_metadata->timestamp; - bpf_map_delete_elem(&ongoing_goroutines, &goroutine_addr); + bpf_map_delete_elem(&ongoing_goroutines, &g_key); } else { trace->go_start_monotime_ns = invocation->start_monotime_ns; } - connection_info_t *info = bpf_map_lookup_elem(&ongoing_server_connections, &goroutine_addr); + connection_info_t *info = bpf_map_lookup_elem(&ongoing_server_connections, &g_key); if (info) { //dbg_print_http_connection_info(info); @@ -295,8 +306,8 @@ int uprobe_ServeHTTPReturns(struct pt_regs *ctx) { bpf_ringbuf_submit(trace, get_flags()); done: - bpf_map_delete_elem(&ongoing_http_server_requests, &goroutine_addr); - bpf_map_delete_elem(&go_trace_map, &goroutine_addr); + bpf_map_delete_elem(&ongoing_http_server_requests, &g_key); + bpf_map_delete_elem(&go_trace_map, &g_key); return 0; } @@ -317,6 +328,8 @@ static __always_inline void roundTripStartHelper(struct pt_regs *ctx) { void *goroutine_addr = GOROUTINE_PTR(ctx); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); void *req = GO_PARAM2(ctx); off_table_t *ot = get_offsets_table(); @@ -362,11 +375,11 @@ static __always_inline void roundTripStartHelper(struct pt_regs *ctx) { bpf_dbg_printk("path: %s", trace.path); // Write event - if (bpf_map_update_elem(&ongoing_http_client_requests, &goroutine_addr, &invocation, BPF_ANY)) { + if (bpf_map_update_elem(&ongoing_http_client_requests, &g_key, &invocation, BPF_ANY)) { bpf_dbg_printk("can't update http client map element"); } - bpf_map_update_elem(&ongoing_http_client_requests_data, &goroutine_addr, &trace, BPF_ANY); + bpf_map_update_elem(&ongoing_http_client_requests_data, &g_key, &trace, BPF_ANY); #ifndef NO_HEADER_PROPAGATION //if (!existing_tp) { @@ -398,16 +411,16 @@ int uprobe_roundTripReturn(struct pt_regs *ctx) { off_table_t *ot = get_offsets_table(); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); - http_func_invocation_t *invocation = - bpf_map_lookup_elem(&ongoing_http_client_requests, &goroutine_addr); + http_func_invocation_t *invocation = bpf_map_lookup_elem(&ongoing_http_client_requests, &g_key); if (invocation == NULL) { bpf_dbg_printk("can't read http invocation metadata"); goto done; } - http_client_data_t *data = - bpf_map_lookup_elem(&ongoing_http_client_requests_data, &goroutine_addr); + http_client_data_t *data = bpf_map_lookup_elem(&ongoing_http_client_requests_data, &g_key); if (data == NULL) { bpf_dbg_printk("can't read http client invocation data"); goto done; @@ -434,7 +447,7 @@ int uprobe_roundTripReturn(struct pt_regs *ctx) { void *resp_ptr = (void *)GO_PARAM1(ctx); - connection_info_t *info = bpf_map_lookup_elem(&ongoing_client_connections, &goroutine_addr); + connection_info_t *info = bpf_map_lookup_elem(&ongoing_client_connections, &g_key); if (info) { __builtin_memcpy(&trace->conn, info, sizeof(connection_info_t)); } else { @@ -459,9 +472,9 @@ int uprobe_roundTripReturn(struct pt_regs *ctx) { bpf_ringbuf_submit(trace, get_flags()); done: - bpf_map_delete_elem(&ongoing_http_client_requests, &goroutine_addr); - bpf_map_delete_elem(&ongoing_http_client_requests_data, &goroutine_addr); - bpf_map_delete_elem(&ongoing_client_connections, &goroutine_addr); + bpf_map_delete_elem(&ongoing_http_client_requests, &g_key); + bpf_map_delete_elem(&ongoing_http_client_requests_data, &g_key); + bpf_map_delete_elem(&ongoing_client_connections, &g_key); return 0; } @@ -483,11 +496,11 @@ int uprobe_writeSubset(struct pt_regs *ctx) { bpf_dbg_printk("Can't find parent go routine for header %llx", header_addr); return 0; } - u64 parent_goaddr = *request_goaddr; + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, (void *)parent_goaddr); - http_func_invocation_t *func_inv = - bpf_map_lookup_elem(&ongoing_http_client_requests, &parent_goaddr); + http_func_invocation_t *func_inv = bpf_map_lookup_elem(&ongoing_http_client_requests, &g_key); if (!func_inv) { bpf_dbg_printk("Can't find client request for goroutine %llx", parent_goaddr); goto done; @@ -551,15 +564,19 @@ int uprobe_http2ResponseWriterStateWriteHeader(struct pt_regs *ctx) { void *goroutine_addr = GOROUTINE_PTR(ctx); u64 status = (u64)GO_PARAM2(ctx); bpf_dbg_printk("goroutine_addr %lx, status %d", goroutine_addr, status); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); server_http_func_invocation_t *invocation = - bpf_map_lookup_elem(&ongoing_http_server_requests, &goroutine_addr); + bpf_map_lookup_elem(&ongoing_http_server_requests, &g_key); if (invocation == NULL) { - void *parent_go = (void *)find_parent_goroutine(goroutine_addr); + void *parent_go = (void *)find_parent_goroutine(&g_key); if (parent_go) { bpf_dbg_printk("found parent goroutine for header [%llx]", parent_go); - invocation = bpf_map_lookup_elem(&ongoing_http_server_requests, &parent_go); + goroutine_key_t p_key = {}; + goroutine_key_from_id(&p_key, parent_go); + invocation = bpf_map_lookup_elem(&ongoing_http_server_requests, &p_key); goroutine_addr = parent_go; } if (!invocation) { @@ -584,6 +601,9 @@ int uprobe_http2serverConn_runHandler(struct pt_regs *ctx) { void *sc = GO_PARAM1(ctx); off_table_t *ot = get_offsets_table(); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); + if (sc) { void *conn_ptr = 0; bpf_probe_read( @@ -596,7 +616,7 @@ int uprobe_http2serverConn_runHandler(struct pt_regs *ctx) { if (conn_conn_ptr) { connection_info_t conn = {0}; get_conn_info(conn_conn_ptr, &conn); - bpf_map_update_elem(&ongoing_server_connections, &goroutine_addr, &conn, BPF_ANY); + bpf_map_update_elem(&ongoing_server_connections, &g_key, &conn, BPF_ANY); } } } @@ -643,8 +663,10 @@ int uprobe_http2RoundTrip(struct pt_regs *ctx) { if (ok) { void *goroutine_addr = GOROUTINE_PTR(ctx); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); - bpf_map_update_elem(&ongoing_client_connections, &goroutine_addr, &conn, BPF_ANY); + bpf_map_update_elem(&ongoing_client_connections, &g_key, &conn, BPF_ANY); } } @@ -678,7 +700,7 @@ typedef struct framer_func_invocation { struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: go routine doing framer write headers + __type(key, goroutine_key_t); // key: go routine doing framer write headers __type( value, framer_func_invocation_t); // the goroutine of the round trip request, which is the key for our traceparent info @@ -708,8 +730,10 @@ int uprobe_http2FramerWriteHeaders(struct pt_regs *ctx) { if (go_ptr) { void *go_addr = *go_ptr; bpf_dbg_printk("Found existing stream data goaddr = %llx", go_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, go_addr); - http_func_invocation_t *info = bpf_map_lookup_elem(&ongoing_http_client_requests, &go_addr); + http_func_invocation_t *info = bpf_map_lookup_elem(&ongoing_http_client_requests, &g_key); if (info) { bpf_dbg_printk("Found func info %llx", info); @@ -735,8 +759,10 @@ int uprobe_http2FramerWriteHeaders(struct pt_regs *ctx) { .framer_ptr = (u64)framer, .initial_n = n, }; + goroutine_key_t f_key = {}; + goroutine_key_from_id(&f_key, goroutine_addr); - bpf_map_update_elem(&framer_invocation_map, &goroutine_addr, &f_info, BPF_ANY); + bpf_map_update_elem(&framer_invocation_map, &f_key, &f_info, BPF_ANY); } else { bpf_dbg_printk("N too large, ignoring..."); } @@ -764,8 +790,10 @@ int uprobe_http2FramerWriteHeaders_returns(struct pt_regs *ctx) { void *goroutine_addr = GOROUTINE_PTR(ctx); off_table_t *ot = get_offsets_table(); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); - framer_func_invocation_t *f_info = bpf_map_lookup_elem(&framer_invocation_map, &goroutine_addr); + framer_func_invocation_t *f_info = bpf_map_lookup_elem(&framer_invocation_map, &g_key); if (f_info) { void *w_ptr = 0; @@ -850,7 +878,7 @@ int uprobe_http2FramerWriteHeaders_returns(struct pt_regs *ctx) { } } - bpf_map_delete_elem(&framer_invocation_map, &goroutine_addr); + bpf_map_delete_elem(&framer_invocation_map, &g_key); return 0; } #else @@ -865,8 +893,11 @@ int uprobe_connServe(struct pt_regs *ctx) { void *goroutine_addr = GOROUTINE_PTR(ctx); bpf_dbg_printk("=== uprobe/proc http conn serve goroutine %lx === ", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); + connection_info_t conn = {0}; - bpf_map_update_elem(&ongoing_server_connections, &goroutine_addr, &conn, BPF_ANY); + bpf_map_update_elem(&ongoing_server_connections, &g_key, &conn, BPF_ANY); return 0; } @@ -876,7 +907,10 @@ int uprobe_netFdRead(struct pt_regs *ctx) { void *goroutine_addr = GOROUTINE_PTR(ctx); bpf_dbg_printk("=== uprobe/proc netFD read goroutine %lx === ", goroutine_addr); - connection_info_t *conn = bpf_map_lookup_elem(&ongoing_server_connections, &goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); + + connection_info_t *conn = bpf_map_lookup_elem(&ongoing_server_connections, &g_key); if (conn) { bpf_dbg_printk( @@ -897,7 +931,10 @@ int uprobe_connServeRet(struct pt_regs *ctx) { bpf_dbg_printk("=== uprobe/proc http conn serve ret === "); void *goroutine_addr = GOROUTINE_PTR(ctx); - bpf_map_delete_elem(&ongoing_server_connections, &goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); + + bpf_map_delete_elem(&ongoing_server_connections, &g_key); return 0; } @@ -909,9 +946,10 @@ int uprobe_persistConnRoundTrip(struct pt_regs *ctx) { off_table_t *ot = get_offsets_table(); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); - http_func_invocation_t *invocation = - bpf_map_lookup_elem(&ongoing_http_client_requests, &goroutine_addr); + http_func_invocation_t *invocation = bpf_map_lookup_elem(&ongoing_http_client_requests, &g_key); if (!invocation) { bpf_dbg_printk("can't find invocation info for client call, this might be a bug"); return 0; @@ -953,7 +991,7 @@ int uprobe_persistConnRoundTrip(struct pt_regs *ctx) { tp_clone(&tp_p.tp, &invocation->tp); tp_p.tp.ts = bpf_ktime_get_ns(); bpf_dbg_printk("storing trace_map info for black-box tracing"); - bpf_map_update_elem(&ongoing_client_connections, &goroutine_addr, &conn, BPF_ANY); + bpf_map_update_elem(&ongoing_client_connections, &g_key, &conn, BPF_ANY); // Must sort the connection info, this map is shared with kprobes which use sorted connection // info always. diff --git a/bpf/go_runtime.h b/bpf/go_runtime.h index 92b92852e..157d558eb 100644 --- a/bpf/go_runtime.h +++ b/bpf/go_runtime.h @@ -20,7 +20,7 @@ typedef struct new_func_invocation { struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: pointer to the request goroutine + __type(key, goroutine_key_t); // key: pointer to the request goroutine __type(value, new_func_invocation_t); __uint(max_entries, MAX_CONCURRENT_REQUESTS); } newproc1 SEC(".maps"); @@ -32,9 +32,11 @@ int uprobe_proc_newproc1(struct pt_regs *ctx) { bpf_dbg_printk("creator_goroutine_addr %lx", creator_goroutine); new_func_invocation_t invocation = {.parent = (u64)GO_PARAM2(ctx)}; + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, creator_goroutine); // Save the registers on invocation to be able to fetch the arguments at return of newproc1 - if (bpf_map_update_elem(&newproc1, &creator_goroutine, &invocation, BPF_ANY)) { + if (bpf_map_update_elem(&newproc1, &g_key, &invocation, BPF_ANY)) { bpf_dbg_printk("can't update map element"); } @@ -45,10 +47,14 @@ SEC("uprobe/runtime_newproc1_return") int uprobe_proc_newproc1_ret(struct pt_regs *ctx) { bpf_dbg_printk("=== uprobe/proc newproc1 returns === "); void *creator_goroutine = GOROUTINE_PTR(ctx); + u64 pid_tid = bpf_get_current_pid_tgid(); + u32 pid = pid_from_pid_tgid(pid_tid); + goroutine_key_t c_key = {.addr = (u64)creator_goroutine, .pid = pid}; + bpf_dbg_printk("creator_goroutine_addr %lx", creator_goroutine); // Lookup the newproc1 invocation metadata - new_func_invocation_t *invocation = bpf_map_lookup_elem(&newproc1, &creator_goroutine); + new_func_invocation_t *invocation = bpf_map_lookup_elem(&newproc1, &c_key); if (invocation == NULL) { bpf_dbg_printk("can't read newproc1 invocation metadata"); goto done; @@ -62,17 +68,20 @@ int uprobe_proc_newproc1_ret(struct pt_regs *ctx) { void *goroutine_addr = (void *)GO_PARAM1(ctx); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {.addr = (u64)goroutine_addr, .pid = pid}; + goroutine_key_t p_key = {.addr = (u64)parent_goroutine, .pid = pid}; + goroutine_metadata metadata = { .timestamp = bpf_ktime_get_ns(), - .parent = (u64)parent_goroutine, + .parent = p_key, }; - if (bpf_map_update_elem(&ongoing_goroutines, &goroutine_addr, &metadata, BPF_ANY)) { + if (bpf_map_update_elem(&ongoing_goroutines, &g_key, &metadata, BPF_ANY)) { bpf_dbg_printk("can't update active goroutine"); } done: - bpf_map_delete_elem(&newproc1, &creator_goroutine); + bpf_map_delete_elem(&newproc1, &c_key); return 0; } @@ -84,10 +93,15 @@ int uprobe_proc_goexit1(struct pt_regs *ctx) { void *goroutine_addr = GOROUTINE_PTR(ctx); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); - bpf_map_delete_elem(&ongoing_goroutines, &goroutine_addr); + u64 pid_tid = bpf_get_current_pid_tgid(); + u32 pid = pid_from_pid_tgid(pid_tid); + + goroutine_key_t g_key = {.addr = (u64)goroutine_addr, .pid = pid}; + + bpf_map_delete_elem(&ongoing_goroutines, &g_key); // We also clean-up the go routine based trace map, it's an LRU // but at this point we are sure we don't need the data. - bpf_map_delete_elem(&go_trace_map, &goroutine_addr); + bpf_map_delete_elem(&go_trace_map, &g_key); return 0; } diff --git a/bpf/go_sarama.h b/bpf/go_sarama.h index d26474f07..f31680587 100644 --- a/bpf/go_sarama.h +++ b/bpf/go_sarama.h @@ -25,8 +25,8 @@ struct { struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: goroutine id - __type(value, u32); // correlation id + __type(key, goroutine_key_t); // key: goroutine id + __type(value, u32); // correlation id __uint(max_entries, MAX_CONCURRENT_REQUESTS); } ongoing_kafka_requests SEC(".maps"); @@ -38,6 +38,8 @@ int uprobe_sarama_sendInternal(struct pt_regs *ctx) { off_table_t *ot = get_offsets_table(); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); u32 correlation_id = 0; @@ -50,8 +52,7 @@ int uprobe_sarama_sendInternal(struct pt_regs *ctx) { if (correlation_id) { bpf_dbg_printk("correlation_id = %d", correlation_id); - if (bpf_map_update_elem( - &ongoing_kafka_requests, &goroutine_addr, &correlation_id, BPF_ANY)) { + if (bpf_map_update_elem(&ongoing_kafka_requests, &g_key, &correlation_id, BPF_ANY)) { bpf_dbg_printk("can't update kafka requests element"); } } @@ -65,8 +66,10 @@ int uprobe_sarama_broker_write(struct pt_regs *ctx) { void *goroutine_addr = GOROUTINE_PTR(ctx); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); - u32 *invocation = bpf_map_lookup_elem(&ongoing_kafka_requests, &goroutine_addr); + u32 *invocation = bpf_map_lookup_elem(&ongoing_kafka_requests, &g_key); void *b_ptr = GO_PARAM1(ctx); void *buf_ptr = GO_PARAM2(ctx); off_table_t *ot = get_offsets_table(); @@ -122,7 +125,7 @@ int uprobe_sarama_broker_write(struct pt_regs *ctx) { } } - bpf_map_delete_elem(&ongoing_kafka_requests, &goroutine_addr); + bpf_map_delete_elem(&ongoing_kafka_requests, &g_key); return 0; } diff --git a/bpf/go_sql.h b/bpf/go_sql.h index 4a4517462..349941e8e 100644 --- a/bpf/go_sql.h +++ b/bpf/go_sql.h @@ -35,7 +35,7 @@ typedef struct sql_func_invocation { struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); - __type(key, void *); // key: pointer to the request goroutine + __type(key, goroutine_key_t); // key: pointer to the request goroutine __type(value, sql_func_invocation_t); __uint(max_entries, MAX_CONCURRENT_REQUESTS); } ongoing_sql_queries SEC(".maps"); @@ -48,9 +48,11 @@ static __always_inline void set_sql_info(void *goroutine_addr, void *sql_param, // We don't look up in the headers, no http/grpc request, therefore 0 as last argument client_trace_parent(goroutine_addr, &invocation.tp, 0); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); // Write event - if (bpf_map_update_elem(&ongoing_sql_queries, &goroutine_addr, &invocation, BPF_ANY)) { + if (bpf_map_update_elem(&ongoing_sql_queries, &g_key, &invocation, BPF_ANY)) { bpf_dbg_printk("can't update map element"); } } @@ -85,13 +87,15 @@ int uprobe_queryReturn(struct pt_regs *ctx) { bpf_dbg_printk("=== uprobe/query return === "); void *goroutine_addr = GOROUTINE_PTR(ctx); bpf_dbg_printk("goroutine_addr %lx", goroutine_addr); + goroutine_key_t g_key = {}; + goroutine_key_from_id(&g_key, goroutine_addr); - sql_func_invocation_t *invocation = bpf_map_lookup_elem(&ongoing_sql_queries, &goroutine_addr); + sql_func_invocation_t *invocation = bpf_map_lookup_elem(&ongoing_sql_queries, &g_key); if (invocation == NULL) { bpf_dbg_printk("Request not found for this goroutine"); return 0; } - bpf_map_delete_elem(&ongoing_sql_queries, &goroutine_addr); + bpf_map_delete_elem(&ongoing_sql_queries, &g_key); sql_request_trace *trace = bpf_ringbuf_reserve(&events, sizeof(sql_request_trace), 0); if (trace) { diff --git a/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.go index 0288fc704..6f6d0982f 100644 --- a/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.go @@ -19,8 +19,13 @@ type bpfConnectionInfoT struct { D_port uint16 } +type bpfGoroutineKeyT struct { + Pid uint64 + Addr uint64 +} + type bpfGoroutineMetadata struct { - Parent uint64 + Parent bpfGoroutineKeyT Timestamp uint64 } diff --git a/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.o index 876c67117..b4e2ab4eb 100644 --- a/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e95ce216c708c525841753d5b0d9b1377f84367748fdec5e11e548881f1fc09c -size 386880 +oid sha256:de6e87481f0aae98861d5c6a0f005df822626e0582e5b8170b77154f48e5e858 +size 390064 diff --git a/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.go index febd00a22..ca9b232dd 100644 --- a/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.go @@ -19,8 +19,13 @@ type bpf_debugConnectionInfoT struct { D_port uint16 } +type bpf_debugGoroutineKeyT struct { + Pid uint64 + Addr uint64 +} + type bpf_debugGoroutineMetadata struct { - Parent uint64 + Parent bpf_debugGoroutineKeyT Timestamp uint64 } diff --git a/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.o index d27972ed1..5cb7c51d5 100644 --- a/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_debug_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c61900617a1b66d410a42fb1069c8d8d71322d6567a4180b46baba5b887936c1 -size 868872 +oid sha256:a08cbf8cbe407f827fbab1c286e625e6f53b8e3b72a104dbd99e679cedc5683d +size 876392 diff --git a/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.go index fe6972da7..603dce16c 100644 --- a/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.go @@ -19,8 +19,13 @@ type bpf_debugConnectionInfoT struct { D_port uint16 } +type bpf_debugGoroutineKeyT struct { + Pid uint64 + Addr uint64 +} + type bpf_debugGoroutineMetadata struct { - Parent uint64 + Parent bpf_debugGoroutineKeyT Timestamp uint64 } diff --git a/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.o index 23fe2c14c..b474d78de 100644 --- a/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_debug_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1d3396d67d3222843ff6c4ca013174c8b27cfa99782ab027999e0ca359d980bc -size 870704 +oid sha256:2c638b5a143f1249ac2cc9f5dc1378daa3f0ac8989d305cfc80faa924eaa78d3 +size 878224 diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.go index b1327512a..b6d166211 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.go @@ -25,8 +25,13 @@ type bpf_tpFramerFuncInvocationT struct { InitialN int64 } +type bpf_tpGoroutineKeyT struct { + Pid uint64 + Addr uint64 +} + type bpf_tpGoroutineMetadata struct { - Parent uint64 + Parent bpf_tpGoroutineKeyT Timestamp uint64 } diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.o index f2cfb900c..8ca882297 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_tp_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:385b77c64b84cf75ee53724418f578874be13b56b94fbc31af4b5a8f00c513b2 -size 432168 +oid sha256:7df80fee3825d147b9a5b2af94cb3820e2d1544baa3812b3b6052809c5eb01c0 +size 436264 diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.go index 8f4421346..a4d6bd986 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.go @@ -25,8 +25,13 @@ type bpf_tp_debugFramerFuncInvocationT struct { InitialN int64 } +type bpf_tp_debugGoroutineKeyT struct { + Pid uint64 + Addr uint64 +} + type bpf_tp_debugGoroutineMetadata struct { - Parent uint64 + Parent bpf_tp_debugGoroutineKeyT Timestamp uint64 } diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.o index 81ef27d8e..6d578ff13 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_tp_debug_arm64_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c62eaa7a75a368b73278be9645fef6405974fe5b3bff210504c39e244c60fede -size 965336 +oid sha256:a458aa266a547092976a30758a33060b5e8b7d8a46f77051600aa2f5695b9f7e +size 973912 diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.go index 7e50910d4..a97386482 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.go @@ -25,8 +25,13 @@ type bpf_tp_debugFramerFuncInvocationT struct { InitialN int64 } +type bpf_tp_debugGoroutineKeyT struct { + Pid uint64 + Addr uint64 +} + type bpf_tp_debugGoroutineMetadata struct { - Parent uint64 + Parent bpf_tp_debugGoroutineKeyT Timestamp uint64 } diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.o index c46f6e124..8ae94652d 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_tp_debug_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56992e4a95a5ee6c9504d20658915b4a1ba2a5b23187fc0da62b34715a6cef23 -size 967160 +oid sha256:2a20e08826189ebbfd20b052849d23dbb8f5ba61d8872868d06604aa22cd7527 +size 975736 diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.go index 19de31e42..19544b597 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.go @@ -25,8 +25,13 @@ type bpf_tpFramerFuncInvocationT struct { InitialN int64 } +type bpf_tpGoroutineKeyT struct { + Pid uint64 + Addr uint64 +} + type bpf_tpGoroutineMetadata struct { - Parent uint64 + Parent bpf_tpGoroutineKeyT Timestamp uint64 } diff --git a/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.o index 74d293188..13d1c2950 100644 --- a/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_tp_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d5f8f5c682f49f2b91df7cf924c06970f7765df84fbfe7e095596d59ad04484 -size 434000 +oid sha256:ca0ed049eda7f6342167a21ce32d108dd460d0b0a70c552b687c2d0a0ea03132 +size 438096 diff --git a/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.go b/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.go index 71a9972a7..2ca52cc37 100644 --- a/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.go +++ b/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.go @@ -19,8 +19,13 @@ type bpfConnectionInfoT struct { D_port uint16 } +type bpfGoroutineKeyT struct { + Pid uint64 + Addr uint64 +} + type bpfGoroutineMetadata struct { - Parent uint64 + Parent bpfGoroutineKeyT Timestamp uint64 } diff --git a/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.o b/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.o index 2b9f9277f..a3bb36bce 100644 --- a/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.o +++ b/pkg/internal/ebpf/gotracer/bpf_x86_bpfel.o @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5f0e23fa1230696dded45405478fe43735682338a8568ca049a59ba53fb83d2 -size 388712 +oid sha256:b3ec207a3bb7f3a21d02c661643ad13b7d0e5c9ea9d20d1e53bd6d14b9c911c9 +size 391896