Sfoglia il codice sorgente

Feature #TASK_QT-18250 提交代码,解决bug

rock.wu 7 mesi fa
parent
commit
d20bc56b83
1 ha cambiato i file con 43 aggiunte e 29 eliminazioni
  1. 43 29
      ebpftracer/ebpf/utrace/go/net/grpc.server.probe.bpf.c

+ 43 - 29
ebpftracer/ebpf/utrace/go/net/grpc.server.probe.bpf.c

@@ -33,6 +33,15 @@ struct grpc_header_ctx_t {
     u32 frame_stream_id_pod_offset;
 };
 
+// 用于处理头部的临时结构,减少栈使用
+struct grpc_header_work_t {
+    struct hpack_header_field hf;
+    char val[W3C_VAL_LENGTH];
+    u32 part1;
+    u32 part2;
+    u32 part3;
+};
+
 struct {
     __uint(type, BPF_MAP_TYPE_HASH);
     __type(key, void *);
@@ -70,6 +79,14 @@ struct {
     __uint(max_entries, 1);
 } grpc_header_ctx_storage SEC(".maps");
 
+// 工作缓冲区,避免栈空间超限
+struct {
+    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+    __uint(key_size, sizeof(u32));
+    __uint(value_size, sizeof(struct grpc_header_work_t));
+    __uint(max_entries, 1);
+} grpc_header_work_storage SEC(".maps");
+
 struct hpack_header_field {
     struct go_string_ot name;
     struct go_string_ot value;
@@ -512,13 +529,20 @@ PROGUP(grpc_server_process_headers)(struct pt_regs *ctx) {
         return -1;
     }
     
+    // 获取工作缓冲区,避免栈溢出
+    struct grpc_header_work_t *work = 
+        bpf_map_lookup_elem(&grpc_header_work_storage, &zero);
+    if (work == NULL) {
+        return -1;
+    }
+    
     void *frame_ptr = header_ctx->frame_ptr;
     void *header_fields_ptr = header_ctx->header_fields_ptr;
     s64 header_fields_len = header_ctx->header_fields_len;
     s32 start_idx = header_ctx->current_index;
     
-    // 每次处理最多 5 个头部,避免指令数过多
-    #define BATCH_SIZE 5
+    // 每次处理最多 3 个头部,进一步减少复杂度
+    #define BATCH_SIZE 3
     s32 end_idx = start_idx + BATCH_SIZE;
     if (end_idx > header_fields_len) {
         end_idx = header_fields_len;
@@ -531,40 +555,35 @@ PROGUP(grpc_server_process_headers)(struct pt_regs *ctx) {
             break;
         }
         
-        // 读取头部字段
-        struct hpack_header_field hf = {};
-        long res = bpf_probe_read(&hf, sizeof(hf), 
-                                   (void *)(header_fields_ptr + (i * sizeof(hf))));
+        // 读取头部字段到 work 缓冲区
+        long res = bpf_probe_read(&work->hf, sizeof(work->hf), 
+                                   (void *)(header_fields_ptr + (i * sizeof(work->hf))));
         if (res != 0) {
             continue;
         }
         
         // 快速检查:长度必须匹配
-        if (hf.name.len != W3C_KEY_LENGTH || hf.value.len != W3C_VAL_LENGTH) {
+        if (work->hf.name.len != W3C_KEY_LENGTH || work->hf.value.len != W3C_VAL_LENGTH) {
             continue;
         }
         
         // 分段比较 "traceparent" (11 字节)
-        // 避免使用 bpf_memcmp,使用简单的整数比较
-        u32 part1 = 0, part2 = 0, part3 = 0;
-        bpf_probe_read(&part1, 4, hf.name.str);      // "trac" = 0x63617274
-        bpf_probe_read(&part2, 4, hf.name.str + 4);  // "epar" = 0x72617065
-        bpf_probe_read(&part3, 3, hf.name.str + 8);  // "ent" = 0x746e65
+        work->part1 = 0;
+        work->part2 = 0;
+        work->part3 = 0;
+        bpf_probe_read(&work->part1, 4, work->hf.name.str);
+        bpf_probe_read(&work->part2, 4, work->hf.name.str + 4);
+        bpf_probe_read(&work->part3, 3, work->hf.name.str + 8);
         
         // 检查是否匹配 "traceparent"
-        if (part1 != 0x63617274 || part2 != 0x72617065 || 
-            (part3 & 0xFFFFFF) != 0x746e65) {
+        if (work->part1 != 0x63617274 || work->part2 != 0x72617065 || 
+            (work->part3 & 0xFFFFFF) != 0x746e65) {
             continue;
         }
         
-        // 找到 traceparent 头部!
-        bpf_printk("grpc:server:operateHeader: found traceparent at index %d", i);
-        
-        // 读取 traceparent 值
-        char val[W3C_VAL_LENGTH];
-        res = bpf_probe_read(val, W3C_VAL_LENGTH, hf.value.str);
+        // 找到 traceparent 头部!读取值到 work 缓冲区
+        res = bpf_probe_read(work->val, W3C_VAL_LENGTH, work->hf.value.str);
         if (res != 0) {
-            bpf_printk("grpc:server:operateHeader: failed to read traceparent value");
             continue;
         }
         
@@ -572,7 +591,6 @@ PROGUP(grpc_server_process_headers)(struct pt_regs *ctx) {
         void *headers_frame = NULL;
         res = bpf_probe_read(&headers_frame, sizeof(headers_frame), frame_ptr);
         if (res != 0) {
-            bpf_printk("grpc:server:operateHeader: failed to read headers_frame");
             continue;
         }
         
@@ -580,27 +598,23 @@ PROGUP(grpc_server_process_headers)(struct pt_regs *ctx) {
         res = bpf_probe_read(&stream_id, sizeof(stream_id), 
                             (void *)(headers_frame + header_ctx->frame_stream_id_pod_offset));
         if (res != 0) {
-            bpf_printk("grpc:server:operateHeader: failed to read stream_id");
             continue;
         }
         
-        bpf_printk("grpc:server:operateHeader: stream_id=%u", stream_id);
-        
         // 使用临时存储
         struct grpc_request_t *grpcReq = 
             bpf_map_lookup_elem(&operate_header_storage, &zero);
         if (grpcReq == NULL) {
-            bpf_printk("grpc:server:operateHeader: failed to get storage");
             return -1;
         }
         
         // 清零并初始化
         __builtin_memset(grpcReq, 0, sizeof(struct grpc_request_t));
         
-        // 解析 W3C trace context (可选,如果需要的话)
-        // w3c_string_to_span_context(val, &grpcReq->psc);
+        // 解析 W3C trace context (可选)
+        // w3c_string_to_span_context(work->val, &grpcReq->psc);
         
-        // 保存到 map,供后续 handleStream 使用
+        // 保存到 map
         bpf_map_update_elem(&streamid_to_grpc_events, &stream_id, grpcReq, 0);
         
         // 找到就退出