|
|
@@ -41,6 +41,14 @@ struct {
|
|
|
__uint(max_entries, MAX_CONCURRENT);
|
|
|
} streamid_to_span_contexts SEC(".maps");
|
|
|
|
|
|
+// 用于 ClientConn_Invoke 函数的临时存储,避免栈空间超限
|
|
|
+struct {
|
|
|
+ __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
|
|
|
+ __uint(key_size, sizeof(u32));
|
|
|
+ __uint(value_size, sizeof(struct grpc_client_request_t));
|
|
|
+ __uint(max_entries, 1);
|
|
|
+} grpc_client_storage_map SEC(".maps");
|
|
|
+
|
|
|
// Injected in init
|
|
|
volatile const u64 clientconn_target_ptr_pos;
|
|
|
volatile const u64 httpclient_nextid_pos;
|
|
|
@@ -78,21 +86,30 @@ int uprobe_ClientConn_Invoke(struct pt_regs *ctx) {
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- struct grpc_client_request_t grpcReq = {};
|
|
|
- grpcReq.start_time = bpf_ktime_get_ns();
|
|
|
+ // 使用 per-cpu array map 存储大变量,避免栈空间超限
|
|
|
+ u32 zero = 0;
|
|
|
+ struct grpc_client_request_t *grpcReq = bpf_map_lookup_elem(&grpc_client_storage_map, &zero);
|
|
|
+ if (grpcReq == NULL) {
|
|
|
+ bpf_printk("grpc:client:ClientConn_Invoke: failed to get storage");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清零并初始化
|
|
|
+ __builtin_memset(grpcReq, 0, sizeof(struct grpc_client_request_t));
|
|
|
+ grpcReq->start_time = bpf_ktime_get_ns();
|
|
|
|
|
|
// Read Method
|
|
|
void *method_ptr = get_argument(ctx, method_ptr_pos);
|
|
|
u64 method_len = (u64)get_argument(ctx, method_len_pos);
|
|
|
- u64 method_size = sizeof(grpcReq.method);
|
|
|
+ u64 method_size = sizeof(grpcReq->method);
|
|
|
method_size = method_size < method_len ? method_size : method_len;
|
|
|
- bpf_probe_read(&grpcReq.method, method_size, method_ptr);
|
|
|
+ bpf_probe_read(&grpcReq->method, method_size, method_ptr);
|
|
|
|
|
|
// Read ClientConn.Target
|
|
|
void *clientconn_ptr = get_argument(ctx, clientconn_pos);
|
|
|
if (!get_go_string_from_user_ptr((void *)(clientconn_ptr + clientconn_target_ptr_pos),
|
|
|
- grpcReq.target,
|
|
|
- sizeof(grpcReq.target))) {
|
|
|
+ grpcReq->target,
|
|
|
+ sizeof(grpcReq->target))) {
|
|
|
bpf_printk("target write failed, aborting ebpf probe");
|
|
|
return 0;
|
|
|
}
|
|
|
@@ -100,16 +117,16 @@ int uprobe_ClientConn_Invoke(struct pt_regs *ctx) {
|
|
|
// start_span_params_t start_span_params = {
|
|
|
// .ctx = ctx,
|
|
|
// .go_context = &go_context,
|
|
|
- // .psc = &grpcReq.psc,
|
|
|
- // .sc = &grpcReq.sc,
|
|
|
+ // .psc = &grpcReq->psc,
|
|
|
+ // .sc = &grpcReq->sc,
|
|
|
// .get_parent_span_context_fn = NULL,
|
|
|
// .get_parent_span_context_arg = NULL,
|
|
|
// };
|
|
|
// start_span(&start_span_params);
|
|
|
|
|
|
// Write event
|
|
|
- bpf_map_update_elem(&grpc_client_events, &key, &grpcReq, 0);
|
|
|
- start_tracking_span(context_ptr_val, &grpcReq.sc);
|
|
|
+ bpf_map_update_elem(&grpc_client_events, &key, grpcReq, 0);
|
|
|
+ start_tracking_span(context_ptr_val, &grpcReq->sc);
|
|
|
return 0;
|
|
|
}
|
|
|
|