|
|
@@ -206,6 +206,46 @@ func (t *Tracer) AttachGoTlsUprobes(pid uint32, appInfo *AppInfo, codeType uint1
|
|
|
return nil, err
|
|
|
}
|
|
|
|
|
|
+ // 检测 gRPC 版本
|
|
|
+ var grpcMajorVersion, grpcMinorVersion int
|
|
|
+ for _, dep := range bi.Deps {
|
|
|
+ if strings.Contains(dep.Path, "grpc") {
|
|
|
+ klog.Infoln("Found gRPC dependency:", dep.Path, "version:", dep.Version)
|
|
|
+
|
|
|
+ // 解析版本号
|
|
|
+ version := dep.Version
|
|
|
+ if version != "" {
|
|
|
+ // 移除可能的 "v" 前缀
|
|
|
+ version = strings.TrimPrefix(version, "v")
|
|
|
+ parts := strings.Split(version, ".")
|
|
|
+
|
|
|
+ if len(parts) >= 2 {
|
|
|
+ major, err := strconv.Atoi(parts[0])
|
|
|
+ if err != nil {
|
|
|
+ klog.WithError(err).Warnf("Error parsing major version from %s", parts[0])
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ minor, err := strconv.Atoi(parts[1])
|
|
|
+ if err != nil {
|
|
|
+ klog.WithError(err).Warnf("Error parsing minor version from %s", parts[1])
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ klog.Infof("Detected gRPC version: %d.%d for PID %d", major, minor, pid)
|
|
|
+ grpcMajorVersion = major
|
|
|
+ grpcMinorVersion = minor
|
|
|
+ // // 根据版本选择相应的探针策略
|
|
|
+ // if major == 1 && minor >= 69 {
|
|
|
+ // klog.Infof("Using modern gRPC handler for version %d.%d", major, minor)
|
|
|
+ // } else {
|
|
|
+ // klog.Infof("Using legacy gRPC handler for version %d.%d", major, minor)
|
|
|
+ // }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
offset, ok := tracer.GetOffset(tracer.NewID("std", "runtime", "g", "goid"), path)
|
|
|
bucketsOff, ok2 := tracer.GetOffset(tracer.NewID("std", "runtime", "hmap", "buckets"), path)
|
|
|
|
|
|
@@ -383,9 +423,10 @@ func (t *Tracer) AttachGoTlsUprobes(pid uint32, appInfo *AppInfo, codeType uint1
|
|
|
// links = append(links, l)
|
|
|
//}
|
|
|
case goGrpcClientConnInvoke:
|
|
|
+ // 根据 gRPC 版本选择相应的探针
|
|
|
l, err := exe.Uprobe(s.Name, t.uprobes["uprobe_ClientConn_Invoke"], &link.UprobeOptions{Address: address})
|
|
|
if err != nil {
|
|
|
- klog.WithError(err).Errorln("failed to attach uprobe_ClientConn_Invoke uprobe")
|
|
|
+ klog.WithError(err).Errorf("failed to attach uprobe_ClientConn_Invoke uprobe")
|
|
|
continue
|
|
|
}
|
|
|
klog.Infoln("uprobe_ClientConn_Invoke ok")
|
|
|
@@ -414,44 +455,49 @@ func (t *Tracer) AttachGoTlsUprobes(pid uint32, appInfo *AppInfo, codeType uint1
|
|
|
links = append(links, l)
|
|
|
}
|
|
|
case goGrpcClientLoopyHeaderHandler:
|
|
|
+ // 根据 gRPC 版本选择相应的探针
|
|
|
l, err := exe.Uprobe(s.Name, t.uprobes["uprobe_LoopyWriter_HeaderHandler"], &link.UprobeOptions{Address: address})
|
|
|
if err != nil {
|
|
|
- klog.WithError(err).Errorln("failed to attach uprobe_LoopyWriter_HeaderHandler uprobe")
|
|
|
+ klog.WithError(err).Errorf("failed to attach uprobe_LoopyWriter_HeaderHandler uprobe")
|
|
|
continue
|
|
|
}
|
|
|
klog.Infoln("uprobe_LoopyWriter_HeaderHandler ok")
|
|
|
links = append(links, l)
|
|
|
case goGrpcHttp2ClientNewStream:
|
|
|
+ // 根据 gRPC 版本选择相应的探针
|
|
|
l, err := exe.Uprobe(s.Name, t.uprobes["uprobe_http2Client_NewStream"], &link.UprobeOptions{Address: address})
|
|
|
if err != nil {
|
|
|
- klog.WithError(err).Errorln("failed to attach uprobe_http2Client_NewStream uprobe")
|
|
|
+ klog.WithError(err).Errorf("failed to attach uprobe_http2Client_NewStream uprobe")
|
|
|
continue
|
|
|
}
|
|
|
klog.Infoln("uprobe_http2Client_NewStream ok")
|
|
|
links = append(links, l)
|
|
|
case goGrpcHttp2OperateHeader:
|
|
|
+ // 根据 gRPC 版本选择相应的探针
|
|
|
l, err := exe.Uprobe(s.Name, t.uprobes["uprobe_http2Server_operateHeader"], &link.UprobeOptions{Address: address})
|
|
|
if err != nil {
|
|
|
- klog.WithError(err).Errorln("failed to attach uprobe_http2Server_operateHeader uprobe")
|
|
|
- continue
|
|
|
- }
|
|
|
- klog.Infoln("goGrpcHttp2OperateHeader ok")
|
|
|
- links = append(links, l)
|
|
|
- case goGrpcServerWritestatus:
|
|
|
- l, err := exe.Uprobe(s.Name, t.uprobes["uprobe_http2Server_WriteStatus"], &link.UprobeOptions{Address: address})
|
|
|
- if err != nil {
|
|
|
- klog.WithError(err).Errorln("failed to attach uprobe_http2Server_WriteStatus uprobe")
|
|
|
+ klog.WithError(err).Errorf("failed to attach uprobe_http2Server_operateHeader uprobe")
|
|
|
continue
|
|
|
}
|
|
|
- klog.Infoln("google.golang.org/grpc/internal/transport.(*http2Server).writeStatus ok")
|
|
|
+ klog.Infoln("uprobe_http2Server_operateHeader ok")
|
|
|
links = append(links, l)
|
|
|
+ // case goGrpcServerWritestatus:
|
|
|
+ // // 根据 gRPC 版本选择相应的 WriteStatus 探针
|
|
|
+ // l, err := exe.Uprobe(s.Name, t.uprobes["uprobe_http2Server_WriteStatus"], &link.UprobeOptions{Address: address})
|
|
|
+ // if err != nil {
|
|
|
+ // klog.WithError(err).Errorf("failed to attach uprobe_http2Server_WriteStatus uprobe")
|
|
|
+ // continue
|
|
|
+ // }
|
|
|
+ // links = append(links, l)
|
|
|
case goGrpcServerHandleStream:
|
|
|
- l, err := exe.Uprobe(s.Name, t.uprobes["uprobe_server_handleStream"], &link.UprobeOptions{Address: address})
|
|
|
+ // 根据 gRPC 版本选择相应的探针
|
|
|
+ probeName := t.selectGRPCServerProbe(grpcMajorVersion, grpcMinorVersion)
|
|
|
+ l, err := exe.Uprobe(s.Name, t.uprobes[probeName], &link.UprobeOptions{Address: address})
|
|
|
if err != nil {
|
|
|
- klog.WithError(err).Errorln("failed to attach uprobe_server_handleStream uprobe")
|
|
|
+ klog.WithError(err).Errorf("failed to attach %s uprobe", probeName)
|
|
|
continue
|
|
|
}
|
|
|
- klog.Infoln("google.golang.org/grpc.(*Server).handleStream ok")
|
|
|
+ klog.Infof("%s ok (gRPC v%d.%d)", probeName, grpcMajorVersion, grpcMinorVersion)
|
|
|
links = append(links, l)
|
|
|
sStart := s.Value - textSection.Addr
|
|
|
sEnd := sStart + s.Size
|
|
|
@@ -651,6 +697,20 @@ func getSslLibPathAndVersion(pid uint32) (string, string) {
|
|
|
return libsslPath, "v" + version
|
|
|
}
|
|
|
|
|
|
+// selectGRPCServerProbe 根据 gRPC 版本选择服务端探针
|
|
|
+func (t *Tracer) selectGRPCServerProbe(major, minor int) string {
|
|
|
+ // 根据 gRPC 版本选择相应的探针
|
|
|
+ if major == 1 && minor >= 69 {
|
|
|
+ // 现代版本 (>= 1.69.0) 使用新的探针
|
|
|
+ klog.Infof("Selecting modern gRPC server probe for version %d.%d", major, minor)
|
|
|
+ return "uprobe_server_handleStream2"
|
|
|
+ } else {
|
|
|
+ // 传统版本 (< 1.69.0) 使用旧的探针
|
|
|
+ klog.Infof("Selecting legacy gRPC server probe for version %d.%d", major, minor)
|
|
|
+ return "uprobe_server_handleStream"
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
func getReturnOffsets(machine elf.Machine, instructions []byte) []int {
|
|
|
var res []int
|
|
|
switch machine {
|