瀏覽代碼

Fixed #TSB-1234 test

ilucky.si 2 年之前
父節點
當前提交
b7e18de464

+ 1 - 0
ebpftracer/ebpf/ebpf.c

@@ -65,4 +65,5 @@
 //#include "l7/openssl.c"
 #include "utrace/go/net/server.probe.bpf.c"
 #include "utrace/go/net/client.probe.bpf.c"
+#include "java/httpurlconnection.bpf.c"
 char _license[] SEC("license") = "GPL";

+ 4 - 0
ebpftracer/ebpf/java/httpurlconnection.bpf.c

@@ -0,0 +1,4 @@
+SEC("uprobe/HandlerFunc_HttpURLConnection_setRequestProperty")
+int uprobe_HandlerFunc_ServeHTTP(struct pt_regs *ctx) {
+	bpf_printk("[uprobe_HttpURLConnection_setRequestProperty]");
+}

+ 0 - 1
ebpftracer/ebpf/java/java_httpurlconnection.c

@@ -1 +0,0 @@
-package java

+ 380 - 380
ebpftracer/ebpf/utrace/go/net/server.probe.bpf.c

@@ -1,392 +1,392 @@
-//// Copyright The OpenTelemetry Authors
-////
-//// Licensed under the Apache License, Version 2.0 (the "License");
-//// you may not use this file except in compliance with the License.
-//// You may obtain a copy of the License at
-////
-////     http://www.apache.org/licenses/LICENSE-2.0
-////
-//// Unless required by applicable law or agreed to in writing, software
-//// distributed under the License is distributed on an "AS IS" BASIS,
-//// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//// See the License for the specific language governing permissions and
-//// limitations under the License.
-//
-//#include "arguments.h"
-//#include "span_context.h"
-//#include "go_context.h"
-//#include "go_types.h"
-//#include "uprobe.h"
-//
-////char __license[] SEC("license") = "Dual MIT/GPL";
-//
-//#define PATH_MAX_LEN 128
-//#define MAX_BUCKETS 8
-//#define METHOD_MAX_LEN 8
-//#define MAX_CONCURRENT 50
-//#define REMOTE_ADDR_MAX_LEN 256
-//#define HOST_MAX_LEN 256
-//#define PROTO_MAX_LEN 8
-//
-//struct http_server_span_t {
-//	BASE_SPAN_PROPERTIES
-//	u64 status_code;
-//	char method[METHOD_MAX_LEN];
-//	char path[PATH_MAX_LEN];
-//	char remote_addr[REMOTE_ADDR_MAX_LEN];
-//	char host[HOST_MAX_LEN];
-//	char proto[PROTO_MAX_LEN];
-//};
-//
-//struct uprobe_data_t {
-//	struct http_server_span_t span;
-//	// bpf2go doesn't support pointers fields
-//	// saving the response pointer in the entry probe
-//	// and using it in the return probe
-//	u64 resp_ptr;
-//};
-//
-//struct {
-//	__uint(type, BPF_MAP_TYPE_HASH);
-//	__type(key, void *);
-//	__type(value, struct uprobe_data_t);
-//	__uint(max_entries, MAX_CONCURRENT);
-//} http_server_uprobes SEC(".maps");
-//
-//struct {
-//	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
-//	__uint(key_size, sizeof(u32));
-//	__uint(value_size, sizeof(struct map_bucket));
-//	__uint(max_entries, 1);
-//} golang_mapbucket_storage_map SEC(".maps");
-//
-//struct {
-//	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
-//	__uint(key_size, sizeof(u32));
-//	__uint(value_size, sizeof(struct cw_header_token));
-//	__uint(max_entries, MAX_CONCURRENT);
-//} header_range SEC(".maps");
-//
-//struct {
-//	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
-//	__uint(key_size, sizeof(u32));
+// Copyright The OpenTelemetry Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "arguments.h"
+#include "span_context.h"
+#include "go_context.h"
+#include "go_types.h"
+#include "uprobe.h"
+
+//char __license[] SEC("license") = "Dual MIT/GPL";
+
+#define PATH_MAX_LEN 128
+#define MAX_BUCKETS 8
+#define METHOD_MAX_LEN 8
+#define MAX_CONCURRENT 50
+#define REMOTE_ADDR_MAX_LEN 256
+#define HOST_MAX_LEN 256
+#define PROTO_MAX_LEN 8
+
+struct http_server_span_t {
+	BASE_SPAN_PROPERTIES
+	u64 status_code;
+	char method[METHOD_MAX_LEN];
+	char path[PATH_MAX_LEN];
+	char remote_addr[REMOTE_ADDR_MAX_LEN];
+	char host[HOST_MAX_LEN];
+	char proto[PROTO_MAX_LEN];
+};
+
+struct uprobe_data_t {
+	struct http_server_span_t span;
+	// bpf2go doesn't support pointers fields
+	// saving the response pointer in the entry probe
+	// and using it in the return probe
+	u64 resp_ptr;
+};
+
+struct {
+	__uint(type, BPF_MAP_TYPE_HASH);
+	__type(key, void *);
+	__type(value, struct uprobe_data_t);
+	__uint(max_entries, MAX_CONCURRENT);
+} http_server_uprobes SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+	__uint(key_size, sizeof(u32));
+	__uint(value_size, sizeof(struct map_bucket));
+	__uint(max_entries, 1);
+} golang_mapbucket_storage_map SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+	__uint(key_size, sizeof(u32));
+	__uint(value_size, sizeof(struct cw_header_token));
+	__uint(max_entries, MAX_CONCURRENT);
+} header_range SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+	__uint(key_size, sizeof(u32));
+	__uint(value_size, sizeof(struct span_context));
+	__uint(max_entries, 1);
+} parent_span_context_storage_map SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+	__uint(key_size, sizeof(u32));
+	__uint(value_size, sizeof(struct apm_span_context));
+	__uint(max_entries, 1);
+} cw_parent_span_context_storage_map SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
+	__uint(key_size, sizeof(u32));
+	__uint(value_size, sizeof(struct uprobe_data_t));
+	__uint(max_entries, 1);
+} http_server_uprobe_storage_map SEC(".maps");
+
+//struct
+//{
+//	__uint(type, BPF_MAP_TYPE_LRU_HASH);
+//	__uint(key_size, sizeof(struct apm_trace_key_t));
 //	__uint(value_size, sizeof(struct span_context));
 //	__uint(max_entries, 1);
-//} parent_span_context_storage_map SEC(".maps");
-//
-//struct {
-//	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
-//	__uint(key_size, sizeof(u32));
-//	__uint(value_size, sizeof(struct apm_span_context));
-//	__uint(max_entries, 1);
-//} cw_parent_span_context_storage_map SEC(".maps");
-//
-//struct {
-//	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
-//	__uint(key_size, sizeof(u32));
-//	__uint(value_size, sizeof(struct uprobe_data_t));
-//	__uint(max_entries, 1);
-//} http_server_uprobe_storage_map SEC(".maps");
-//
-////struct
-////{
-////	__uint(type, BPF_MAP_TYPE_LRU_HASH);
-////	__uint(key_size, sizeof(struct apm_trace_key_t));
-////	__uint(value_size, sizeof(struct span_context));
-////	__uint(max_entries, 1);
-////} apm_span_context_map SEC(".maps");
-//
-//struct {
-//	__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
-//} events SEC(".maps");
-//
-//// Injected in init
-//volatile const u64 method_ptr_pos;
-//volatile const u64 url_ptr_pos;
-//volatile const u64 path_ptr_pos;
-//volatile const u64 ctx_ptr_pos;
-//volatile const u64 headers_ptr_pos;
-//volatile const u64 buckets_ptr_pos;
-//volatile const u64 req_ptr_pos;
-//volatile const u64 status_code_pos;
-//volatile const u64 remote_addr_pos;
-//volatile const u64 host_pos;
-//volatile const u64 proto_pos;
-////for (int i = 0; i < W3C_KEY_LENGTH; i++)
-////{
-////if (current_header_key[i] != "traceparent"[i]){
-////goto outer_loop;
-////}
-////if (current_header_key[i] != "Traceparent"[i]){
-////goto outer_loop;
-////}
-////}
-//
-//static __always_inline struct span_context *extract_context_from_req_headers(void *headers_ptr_ptr) {
-//	void *headers_ptr;
-//	long res;
-//	res = bpf_probe_read(&headers_ptr, sizeof(headers_ptr), headers_ptr_ptr);
-//	if (res < 0) {
-//		return NULL;
-//	}
-//	u64 headers_count = 0;
-//	res = bpf_probe_read(&headers_count, sizeof(headers_count), headers_ptr);
-//	if (res < 0) {
-//		return NULL;
-//	}
-//	if (headers_count == 0) {
-//		return NULL;
-//	}
-//	unsigned char log_2_bucket_count;
-//	res = bpf_probe_read(&log_2_bucket_count, sizeof(log_2_bucket_count), headers_ptr + 9);
-//	if (res < 0) {
-//		return NULL;
-//	}
-//	u64 bucket_count = 1 << log_2_bucket_count;
-//	void *header_buckets;
-//	res = bpf_probe_read(&header_buckets, sizeof(header_buckets), (void *) (headers_ptr + buckets_ptr_pos));
-//	if (res < 0) {
-//		return NULL;
-//	}
-//	u32 map_id = 0;
-//	struct map_bucket *map_value = bpf_map_lookup_elem(&golang_mapbucket_storage_map, &map_id);
-//	if (!map_value) {
-//		return NULL;
-//	}
-//	for (u32 j = 0; j < MAX_BUCKETS; j++) {
-//		if (j >= bucket_count) {
-//			break;
-//		}
-//		res = bpf_probe_read(map_value, sizeof(struct map_bucket), header_buckets + (j * sizeof(struct map_bucket)));
-//		if (res < 0) {
-//			continue;
-//		}
-//		for (u32 i = 0; i < 8; i++) {
-//			if (map_value->tophash[i] == 0) {
+//} apm_span_context_map SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
+} events SEC(".maps");
+
+// Injected in init
+volatile const u64 method_ptr_pos;
+volatile const u64 url_ptr_pos;
+volatile const u64 path_ptr_pos;
+volatile const u64 ctx_ptr_pos;
+volatile const u64 headers_ptr_pos;
+volatile const u64 buckets_ptr_pos;
+volatile const u64 req_ptr_pos;
+volatile const u64 status_code_pos;
+volatile const u64 remote_addr_pos;
+volatile const u64 host_pos;
+volatile const u64 proto_pos;
+//for (int i = 0; i < W3C_KEY_LENGTH; i++)
+//{
+//if (current_header_key[i] != "traceparent"[i]){
+//goto outer_loop;
+//}
+//if (current_header_key[i] != "Traceparent"[i]){
+//goto outer_loop;
+//}
+//}
+
+static __always_inline struct span_context *extract_context_from_req_headers(void *headers_ptr_ptr) {
+	void *headers_ptr;
+	long res;
+	res = bpf_probe_read(&headers_ptr, sizeof(headers_ptr), headers_ptr_ptr);
+	if (res < 0) {
+		return NULL;
+	}
+	u64 headers_count = 0;
+	res = bpf_probe_read(&headers_count, sizeof(headers_count), headers_ptr);
+	if (res < 0) {
+		return NULL;
+	}
+	if (headers_count == 0) {
+		return NULL;
+	}
+	unsigned char log_2_bucket_count;
+	res = bpf_probe_read(&log_2_bucket_count, sizeof(log_2_bucket_count), headers_ptr + 9);
+	if (res < 0) {
+		return NULL;
+	}
+	u64 bucket_count = 1 << log_2_bucket_count;
+	void *header_buckets;
+	res = bpf_probe_read(&header_buckets, sizeof(header_buckets), (void *) (headers_ptr + buckets_ptr_pos));
+	if (res < 0) {
+		return NULL;
+	}
+	u32 map_id = 0;
+	struct map_bucket *map_value = bpf_map_lookup_elem(&golang_mapbucket_storage_map, &map_id);
+	if (!map_value) {
+		return NULL;
+	}
+	for (u32 j = 0; j < MAX_BUCKETS; j++) {
+		if (j >= bucket_count) {
+			break;
+		}
+		res = bpf_probe_read(map_value, sizeof(struct map_bucket), header_buckets + (j * sizeof(struct map_bucket)));
+		if (res < 0) {
+			continue;
+		}
+		for (u32 i = 0; i < 8; i++) {
+			if (map_value->tophash[i] == 0) {
+				continue;
+			}
+			if (map_value->keys[i].len != W3C_KEY_LENGTH) {
+				continue;
+			}
+			char current_header_key[W3C_KEY_LENGTH];
+			bpf_probe_read(current_header_key, sizeof(current_header_key), map_value->keys[i].str);
+			for (int i = 0; i < W3C_KEY_LENGTH; i++) {
+				if (current_header_key[i] != "Traceparent"[i] && current_header_key[i] != "traceparent"[i]) {
+					goto outer_loop;
+				}
+			}
+//			if (!bpf_memcmp(current_header_key, "traceparent", W3C_KEY_LENGTH) && !bpf_memcmp(current_header_key, "Traceparent", W3C_KEY_LENGTH))
+//			{
+//				bpf_printk("not find it");
 //				continue;
 //			}
-//			if (map_value->keys[i].len != W3C_KEY_LENGTH) {
+//			bpf_printk("find it:%s", map_value->keys[i].str);
+			void *traceparent_header_value_ptr = map_value->values[i].array;
+			struct go_string_ot traceparent_header_value_go_str;
+			res = bpf_probe_read(&traceparent_header_value_go_str, sizeof(traceparent_header_value_go_str),
+			                     traceparent_header_value_ptr);
+			// 00-95b5ec2b81e2374a4a27ce36ab71d349-18f65a5a3ab22213-02
+			bpf_printk("traceparent_header_value_go_str.str:%s", traceparent_header_value_go_str.str);
+
+			if (res < 0) {
+				return NULL;
+			}
+//			if (traceparent_header_value_go_str.len != W3C_VAL_LENGTH) {
 //				continue;
 //			}
-//			char current_header_key[W3C_KEY_LENGTH];
-//			bpf_probe_read(current_header_key, sizeof(current_header_key), map_value->keys[i].str);
-//			for (int i = 0; i < W3C_KEY_LENGTH; i++) {
-//				if (current_header_key[i] != "Traceparent"[i] && current_header_key[i] != "traceparent"[i]) {
-//					goto outer_loop;
-//				}
-//			}
-////			if (!bpf_memcmp(current_header_key, "traceparent", W3C_KEY_LENGTH) && !bpf_memcmp(current_header_key, "Traceparent", W3C_KEY_LENGTH))
-////			{
-////				bpf_printk("not find it");
-////				continue;
-////			}
-////			bpf_printk("find it:%s", map_value->keys[i].str);
-//			void *traceparent_header_value_ptr = map_value->values[i].array;
-//			struct go_string_ot traceparent_header_value_go_str;
-//			res = bpf_probe_read(&traceparent_header_value_go_str, sizeof(traceparent_header_value_go_str),
-//			                     traceparent_header_value_ptr);
-//			// 00-95b5ec2b81e2374a4a27ce36ab71d349-18f65a5a3ab22213-02
-//			bpf_printk("traceparent_header_value_go_str.str:%s", traceparent_header_value_go_str.str);
-//
-//			if (res < 0) {
-//				return NULL;
-//			}
-////			if (traceparent_header_value_go_str.len != W3C_VAL_LENGTH) {
-////				continue;
-////			}
-//			char traceparent_header_value[130];
-//			res = bpf_probe_read(&traceparent_header_value, sizeof(traceparent_header_value),
-//			                     traceparent_header_value_go_str.str);
-//			// 00-95b5ec2b81e2374a4a27ce36ab71d349-18f65a5a3ab22213-02��c�����c����@c;
-////			bpf_printk("traceparent_header_value11:[%s]", traceparent_header_value);
-//
-////			bpf_printk("111111111111111111:[%d]", range.start[1]);
-//
-//
-//			if (res < 0) {
-//				return NULL;
+			char traceparent_header_value[130];
+			res = bpf_probe_read(&traceparent_header_value, sizeof(traceparent_header_value),
+			                     traceparent_header_value_go_str.str);
+			// 00-95b5ec2b81e2374a4a27ce36ab71d349-18f65a5a3ab22213-02��c�����c����@c;
+//			bpf_printk("traceparent_header_value11:[%s]", traceparent_header_value);
+
+//			bpf_printk("111111111111111111:[%d]", range.start[1]);
+
+
+			if (res < 0) {
+				return NULL;
+			}
+
+			struct span_context *parent_span_context = bpf_map_lookup_elem(&parent_span_context_storage_map, &map_id);
+			if (!parent_span_context) {
+				bpf_printk("no parent_span_context");
+				return NULL;
+			}
+			struct apm_span_context *cw_parent_span_context = bpf_map_lookup_elem(&cw_parent_span_context_storage_map, &map_id);
+			if (!cw_parent_span_context) {
+				bpf_printk("no cw_parent_span_context");
+				return NULL;
+			}
+
+			w3c_string_to_span_context(traceparent_header_value, parent_span_context);
+
+			cw_string_to_span_context(traceparent_header_value, cw_parent_span_context);
+
+			// 保存sc
+			cw_save_parent_tracking_span(cw_parent_span_context);
+
+
+//            for (int i = 0; i < TRACE_ID_SIZE; i++) {
+//                bpf_printk("%02x", parent_span_context->TraceID[i]);
+//            }
+//			char val[10];
+//			char *out = val;
+//			// Write trace id
+//			bytes_to_hex_string(cw_parent_span_context->type_from, 5, out);
+//			for (int i = 0; i < 10; ++i) {
+//				bpf_printk("traceid--%c",val[i]);
 //			}
+
+
+
 //
-//			struct span_context *parent_span_context = bpf_map_lookup_elem(&parent_span_context_storage_map, &map_id);
-//			if (!parent_span_context) {
-//				bpf_printk("no parent_span_context");
-//				return NULL;
+//			for (int i = 0; i < 1; i++) {
+//				bpf_printk("type_from------%02x", cw_parent_span_context->type_from[i]);
 //			}
-//			struct apm_span_context *cw_parent_span_context = bpf_map_lookup_elem(&cw_parent_span_context_storage_map, &map_id);
-//			if (!cw_parent_span_context) {
-//				bpf_printk("no cw_parent_span_context");
-//				return NULL;
-//			}
-//
-//			w3c_string_to_span_context(traceparent_header_value, parent_span_context);
 //
-//			cw_string_to_span_context(traceparent_header_value, cw_parent_span_context);
-//
-//			// 保存sc
-//			cw_save_parent_tracking_span(cw_parent_span_context);
-//
-//
-////            for (int i = 0; i < TRACE_ID_SIZE; i++) {
-////                bpf_printk("%02x", parent_span_context->TraceID[i]);
-////            }
-////			char val[10];
-////			char *out = val;
+//			char val[2];
+//			char *out = val;
 ////			// Write trace id
-////			bytes_to_hex_string(cw_parent_span_context->type_from, 5, out);
-////			for (int i = 0; i < 10; ++i) {
-////				bpf_printk("traceid--%c",val[i]);
-////			}
-//
+//			bytes_to_hex_string(cw_parent_span_context->type_from, 1, out);
 //
-//
-////
-////			for (int i = 0; i < 1; i++) {
-////				bpf_printk("type_from------%02x", cw_parent_span_context->type_from[i]);
-////			}
-////
-////			char val[2];
-////			char *out = val;
-//////			// Write trace id
-////			bytes_to_hex_string(cw_parent_span_context->type_from, 1, out);
-////
-////			bpf_printk("type_from1--%s", out);
-//
-////			for (int i = 0; i < 10; ++i) {
-////				bpf_printk("traceid--%c",val[i]);
-////			}
-//
-////			bpf_printk("parent_span_context-TraceID2:%s", parent_span_context->TraceID);
-////			bpf_printk("parent_span_context-SpanID2:%s", parent_span_context->SpanID);
-//			return parent_span_context;
-//			outer_loop:
-//			continue;
-//		}
-//	}
-//	return NULL;
-//}
-//
-//// This instrumentation attaches uprobe to the following function:
-//// func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request)
-//SEC("uprobe/HandlerFunc_ServeHTTP")
-//int uprobe_HandlerFunc_ServeHTTP(struct pt_regs *ctx) {
-//	bpf_printk("[uprobe_HandlerFunc_ServeHTTP]");
-//	void *req_ctx_ptr = get_Go_context(ctx, 4, ctx_ptr_pos, false);
-//	void *key = get_consistent_key(ctx, req_ctx_ptr);
-//	void *httpReq_ptr = bpf_map_lookup_elem(&http_server_uprobes, &key);
-//	if (httpReq_ptr != NULL) {
-//		bpf_printk("uprobe/HandlerFunc_ServeHTTP already tracked with the current request");
-//		return 0;
-//	}
-//
-//	u32 map_id = 0;
-//	struct uprobe_data_t *uprobe_data = bpf_map_lookup_elem(&http_server_uprobe_storage_map, &map_id);
-//	if (uprobe_data == NULL) {
-//		bpf_printk("uprobe/HandlerFunc_ServeHTTP: http_server_span is NULL");
-//		return 0;
-//	}
-//
-//	__builtin_memset(uprobe_data, 0, sizeof(struct uprobe_data_t));
-//
-//	// Save response writer
-//	void *resp_impl = get_argument(ctx, 3);
-//	uprobe_data->resp_ptr = (u64) resp_impl;
-//
-//	struct http_server_span_t *http_server_span = &uprobe_data->span;
-//	http_server_span->start_time = bpf_ktime_get_ns();
-//
-//	// Propagate context
-//	void *req_ptr = get_argument(ctx, 4);
-//	struct span_context *parent_ctx = extract_context_from_req_headers((void *) (req_ptr + headers_ptr_pos));
-//	if (parent_ctx != NULL) {
-//		// found parent context in http headers
-//		http_server_span->psc = *parent_ctx;
-//		// copy traceID
-//		copy_byte_arrays(http_server_span->psc.TraceID, http_server_span->sc.TraceID, TRACE_ID_SIZE);
-//		// 生成随机SpanID
-//		generate_random_bytes(http_server_span->sc.SpanID, SPAN_ID_SIZE);
-//	} else {
-//		http_server_span->sc = generate_span_context();
-//	}
-//
-//	if (req_ctx_ptr == NULL) {
-////		bpf_printk("uprobe/HandlerFunc_ServeHTTP: req_ctx_ptr is NULL");
-//		return 0;
-//	}
-////	bpf_printk("found parent context in http headers");
-//
-////	bpf_printk("parent_span_context-TraceID---");
-//
-//
-////    for (int i = 0; i < TRACE_ID_SIZE; i++) {
-////        bpf_printk("%02x", uprobe_data->span.sc.TraceID[i]);
-////    }
-//
-////    bpf_printk("parent_span_context-SpanID---");
-////    for (int i = 0; i < SPAN_ID_SIZE; i++) {
-////        bpf_printk("%02x", uprobe_data->span.sc.SpanID[i]);
-////    }
-//
-////	bpf_map_update_elem(&http_server_uprobes, &key, uprobe_data, 0);
-////	start_tracking_span(req_ctx_ptr, &http_server_span->sc);
-//
-////	void save_tracking_span(struct apm_span_context *sc)
-//
-//	return 0;
-//}
-//
-//void read_go_string(void *base, int offset, char *output, int maxLen, const char *errorMsg) {
-//	void *ptr = (void *) (base + offset);
-//	if (!get_go_string_from_user_ptr(ptr, output, maxLen)) {
-//		bpf_printk("Failed to get %s", errorMsg);
-//	}
-//
-//}
-//
-//// This instrumentation attaches uprobe to the following function:
-//// func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request)
-//SEC("uprobe/HandlerFunc_ServeHTTP")
-//int uprobe_HandlerFunc_ServeHTTP_Returns(struct pt_regs *ctx) {
-//	bpf_printk("[uprobe_HandlerFunc_ServeHTTP_Returns]");
-//	u64 end_time = bpf_ktime_get_ns();
-//	void *req_ctx_ptr = get_Go_context(ctx, 4, ctx_ptr_pos, false);
-//	void *key = get_consistent_key(ctx, req_ctx_ptr);
-//
-//	struct uprobe_data_t *uprobe_data = bpf_map_lookup_elem(&http_server_uprobes, &key);
-//	if (uprobe_data == NULL) {
-//		bpf_printk("uprobe/HandlerFunc_ServeHTTP_Returns: entry_state is NULL");
-//		return 0;
-//	}
-//	bpf_map_delete_elem(&http_server_uprobes, &key);
-//
-//	struct http_server_span_t *http_server_span = &uprobe_data->span;
-//	void *resp_ptr = (void *) uprobe_data->resp_ptr;
-//	void *req_ptr = NULL;
-//	bpf_probe_read(&req_ptr, sizeof(req_ptr), (void *) (resp_ptr + req_ptr_pos));
-//
-//	http_server_span->end_time = end_time;
-//
-//	void *url_ptr = 0;
-//	bpf_probe_read(&url_ptr, sizeof(url_ptr), (void *) (req_ptr + url_ptr_pos));
-//	// Collect fields from response
-//	read_go_string(req_ptr, method_ptr_pos, http_server_span->method, sizeof(http_server_span->method),
-//	               "method from request");
-//	read_go_string(url_ptr, path_ptr_pos, http_server_span->path, sizeof(http_server_span->path),
-//	               "path from Request.URL");
-//	read_go_string(req_ptr, remote_addr_pos, http_server_span->remote_addr, sizeof(http_server_span->remote_addr),
-//	               "remote addr from Request.RemoteAddr");
-//	read_go_string(req_ptr, host_pos, http_server_span->host, sizeof(http_server_span->host), "host from Request.Host");
-//	read_go_string(req_ptr, proto_pos, http_server_span->proto, sizeof(http_server_span->proto),
-//	               "proto from Request.Proto");
-//
-//	// status code
-//	bpf_probe_read(&http_server_span->status_code, sizeof(http_server_span->status_code),
-//	               (void *) (resp_ptr + status_code_pos));
-//
-//	bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, http_server_span, sizeof(*http_server_span));
-//	stop_tracking_span(&http_server_span->sc, &http_server_span->psc);
-//
-//
-//	clear_span_context();
-//	bpf_printk("HTTP_END");
-//	return 0;
-//}
+//			bpf_printk("type_from1--%s", out);
+
+//			for (int i = 0; i < 10; ++i) {
+//				bpf_printk("traceid--%c",val[i]);
+//			}
+
+//			bpf_printk("parent_span_context-TraceID2:%s", parent_span_context->TraceID);
+//			bpf_printk("parent_span_context-SpanID2:%s", parent_span_context->SpanID);
+			return parent_span_context;
+			outer_loop:
+			continue;
+		}
+	}
+	return NULL;
+}
+
+// This instrumentation attaches uprobe to the following function:
+// func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request)
+SEC("uprobe/HandlerFunc_ServeHTTP")
+int uprobe_HandlerFunc_ServeHTTP(struct pt_regs *ctx) {
+	bpf_printk("[uprobe_HandlerFunc_ServeHTTP]");
+	void *req_ctx_ptr = get_Go_context(ctx, 4, ctx_ptr_pos, false);
+	void *key = get_consistent_key(ctx, req_ctx_ptr);
+	void *httpReq_ptr = bpf_map_lookup_elem(&http_server_uprobes, &key);
+	if (httpReq_ptr != NULL) {
+		bpf_printk("uprobe/HandlerFunc_ServeHTTP already tracked with the current request");
+		return 0;
+	}
+
+	u32 map_id = 0;
+	struct uprobe_data_t *uprobe_data = bpf_map_lookup_elem(&http_server_uprobe_storage_map, &map_id);
+	if (uprobe_data == NULL) {
+		bpf_printk("uprobe/HandlerFunc_ServeHTTP: http_server_span is NULL");
+		return 0;
+	}
+
+	__builtin_memset(uprobe_data, 0, sizeof(struct uprobe_data_t));
+
+	// Save response writer
+	void *resp_impl = get_argument(ctx, 3);
+	uprobe_data->resp_ptr = (u64) resp_impl;
+
+	struct http_server_span_t *http_server_span = &uprobe_data->span;
+	http_server_span->start_time = bpf_ktime_get_ns();
+
+	// Propagate context
+	void *req_ptr = get_argument(ctx, 4);
+	struct span_context *parent_ctx = extract_context_from_req_headers((void *) (req_ptr + headers_ptr_pos));
+	if (parent_ctx != NULL) {
+		// found parent context in http headers
+		http_server_span->psc = *parent_ctx;
+		// copy traceID
+		copy_byte_arrays(http_server_span->psc.TraceID, http_server_span->sc.TraceID, TRACE_ID_SIZE);
+		// 生成随机SpanID
+		generate_random_bytes(http_server_span->sc.SpanID, SPAN_ID_SIZE);
+	} else {
+		http_server_span->sc = generate_span_context();
+	}
+
+	if (req_ctx_ptr == NULL) {
+//		bpf_printk("uprobe/HandlerFunc_ServeHTTP: req_ctx_ptr is NULL");
+		return 0;
+	}
+//	bpf_printk("found parent context in http headers");
+
+//	bpf_printk("parent_span_context-TraceID---");
+
+
+//    for (int i = 0; i < TRACE_ID_SIZE; i++) {
+//        bpf_printk("%02x", uprobe_data->span.sc.TraceID[i]);
+//    }
+
+//    bpf_printk("parent_span_context-SpanID---");
+//    for (int i = 0; i < SPAN_ID_SIZE; i++) {
+//        bpf_printk("%02x", uprobe_data->span.sc.SpanID[i]);
+//    }
+
+//	bpf_map_update_elem(&http_server_uprobes, &key, uprobe_data, 0);
+//	start_tracking_span(req_ctx_ptr, &http_server_span->sc);
+
+//	void save_tracking_span(struct apm_span_context *sc)
+
+	return 0;
+}
+
+void read_go_string(void *base, int offset, char *output, int maxLen, const char *errorMsg) {
+	void *ptr = (void *) (base + offset);
+	if (!get_go_string_from_user_ptr(ptr, output, maxLen)) {
+		bpf_printk("Failed to get %s", errorMsg);
+	}
+
+}
+
+// This instrumentation attaches uprobe to the following function:
+// func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request)
+SEC("uprobe/HandlerFunc_ServeHTTP")
+int uprobe_HandlerFunc_ServeHTTP_Returns(struct pt_regs *ctx) {
+	bpf_printk("[uprobe_HandlerFunc_ServeHTTP_Returns]");
+	u64 end_time = bpf_ktime_get_ns();
+	void *req_ctx_ptr = get_Go_context(ctx, 4, ctx_ptr_pos, false);
+	void *key = get_consistent_key(ctx, req_ctx_ptr);
+
+	struct uprobe_data_t *uprobe_data = bpf_map_lookup_elem(&http_server_uprobes, &key);
+	if (uprobe_data == NULL) {
+		bpf_printk("uprobe/HandlerFunc_ServeHTTP_Returns: entry_state is NULL");
+		return 0;
+	}
+	bpf_map_delete_elem(&http_server_uprobes, &key);
+
+	struct http_server_span_t *http_server_span = &uprobe_data->span;
+	void *resp_ptr = (void *) uprobe_data->resp_ptr;
+	void *req_ptr = NULL;
+	bpf_probe_read(&req_ptr, sizeof(req_ptr), (void *) (resp_ptr + req_ptr_pos));
+
+	http_server_span->end_time = end_time;
+
+	void *url_ptr = 0;
+	bpf_probe_read(&url_ptr, sizeof(url_ptr), (void *) (req_ptr + url_ptr_pos));
+	// Collect fields from response
+	read_go_string(req_ptr, method_ptr_pos, http_server_span->method, sizeof(http_server_span->method),
+	               "method from request");
+	read_go_string(url_ptr, path_ptr_pos, http_server_span->path, sizeof(http_server_span->path),
+	               "path from Request.URL");
+	read_go_string(req_ptr, remote_addr_pos, http_server_span->remote_addr, sizeof(http_server_span->remote_addr),
+	               "remote addr from Request.RemoteAddr");
+	read_go_string(req_ptr, host_pos, http_server_span->host, sizeof(http_server_span->host), "host from Request.Host");
+	read_go_string(req_ptr, proto_pos, http_server_span->proto, sizeof(http_server_span->proto),
+	               "proto from Request.Proto");
+
+	// status code
+	bpf_probe_read(&http_server_span->status_code, sizeof(http_server_span->status_code),
+	               (void *) (resp_ptr + status_code_pos));
+
+	bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, http_server_span, sizeof(*http_server_span));
+	stop_tracking_span(&http_server_span->sc, &http_server_span->psc);
+
+
+	clear_span_context();
+	bpf_printk("HTTP_END");
+	return 0;
+}

+ 18 - 19
ebpftracer/tls.go

@@ -7,7 +7,6 @@ import (
 	"debug/elf"
 	"errors"
 	"fmt"
-	"github.com/cilium/ebpf"
 	"github.com/coroot/coroot-node-agent/ebpftracer/tracer"
 	"os"
 	"regexp"
@@ -139,27 +138,27 @@ func (t *Tracer) AttachTlsUprobes4Java(pid uint32) []link.Link {
 	var links []link.Link
 	// 733f8cc7aaa0 fd0 Lsun/net/www/protocol/http/HttpURLConnection;::setRequestProperty
 	// 参考: l, err := exe.Uprobe(s.Name, t.uprobes["uprobe_Transport_roundTrip"], &link.UprobeOptions{Address: address})
-	spec := &ebpf.ProgramSpec{
-		Name: "uprobe_HttpURLConnection_setRequestProperty",
-		Type: ebpf.Kprobe,
-		//// AttachTo: "uprobe_HttpURLConnection_setRequestProperty",
-		//Instructions: asm.Instructions{
-		//	asm.Instruction{OpCode: Opcode. },
-		//},
-		// Type:    ebpf.TracePoint,
-		License: "GPL",
-	}
-	println("&ebpf.ProgramSpec: ", spec)
-	prog, err := ebpf.NewProgram(spec) // func NewProgram(spec *ProgramSpec) (*Program, error) {
-	if err != nil {
-		fmt.Println("NewProgram: ", err)
-		return nil
-	}
+	//spec := &ebpf.ProgramSpec{
+	//	Name: "uprobe_HttpURLConnection_setRequestProperty",
+	//	Type: ebpf.Kprobe,
+	//	//// AttachTo: "uprobe_HttpURLConnection_setRequestProperty",
+	//	//Instructions: asm.Instructions{
+	//	//	asm.Instruction{OpCode: Opcode. },
+	//	//},
+	//	// Type:    ebpf.TracePoint,
+	//	License: "GPL",
+	//}
+	//println("&ebpf.ProgramSpec: ", spec)
+	//prog, err := ebpf.NewProgram(spec) // func NewProgram(spec *ProgramSpec) (*Program, error) {
+	//if err != nil {
+	//	fmt.Println("NewProgram: ", err)
+	//	return nil
+	//}
 
 	// prog = t.uprobes["uprobe_HttpURLConnection::setRequestProperty"] //
-	fmt.Println("OpenExecutable error: ", prog)
+	// fmt.Println("OpenExecutable error: ", prog)
 
-	link, err := exe.Uprobe("Lsun/net/www/protocol/http/HttpURLConnection;::setRequestProperty", prog, &link.UprobeOptions{Address: 0x733f8cc7aaa0})
+	link, err := exe.Uprobe("Lsun/net/www/protocol/http/HttpURLConnection;::setRequestProperty", t.uprobes["uprobe_HttpURLConnection_setRequestProperty"], &link.UprobeOptions{Address: 0x733f8cc7aaa0})
 	if err != nil {
 		fmt.Println("exe.Uprobe error: ", err) // 报错: TODO: exe.Uprobe error:  prog cannot be nil: invalid input
 		return nil

+ 3 - 3
ebpftracer/tracer.go

@@ -299,9 +299,9 @@ func (t *Tracer) ebpf(ch chan<- Event) error {
 		// ITEST............ProgramSpec:   uprobe_HandlerFunc_ServeHTTP_Returns Kprobe None HandlerFunc_ServeHTTP GPL
 		// ITEST............Program:  uprobe_HandlerFunc_ServeHTTP_Returns uprobe/HandlerFunc_ServeHTTP Kprobe Kprobe(uprobe_HandlerFunc_ServeHTTP_Returns)#131
 		fmt.Println("ITEST............ProgramSpec:  ", programSpec.Name, programSpec.Type, programSpec.AttachType, programSpec.AttachTo, programSpec.License)
-		if strings.Contains(programSpec.Name, "HandlerFunc_ServeHTTP") {
-			fmt.Println("ITEST............ProgramSpec:  ", programSpec.Instructions)
-		}
+		//if strings.Contains(programSpec.Name, "HandlerFunc_ServeHTTP") {
+		//	fmt.Println("ITEST............ProgramSpec:  ", programSpec.Instructions)
+		//}
 
 		program := t.collection.Programs[programSpec.Name]                                                              // TODO: 核心过程, 从tracer.uprobes中获取对应的program, 在哪来放进去的呢? ebpf.NewCollectionWithOptions(collectionSpec, *opts)
 		fmt.Println("ITEST............Program: ", programSpec.Name, programSpec.SectionName, programSpec.Type, program) // 示例: bpf_func_sys_exit_readv tracepoint/syscalls/sys_exit_readv TracePoint | uprobe_HandlerFunc_ServeHTTP uprobe/HandlerFunc_ServeHTTP Kprobe