This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-rover.git


The following commit(s) were added to refs/heads/main by this push:
     new d8e4645  Enhance compatibility when profiling with SSL (#96)
d8e4645 is described below

commit d8e4645c0fda1fa9b972d2e1172e151b938a3f51
Author: mrproliu <[email protected]>
AuthorDate: Fri Aug 11 17:58:49 2023 +0800

    Enhance compatibility when profiling with SSL (#96)
---
 CHANGES.md                                         |  1 +
 .../task/network/analyze/buffer/buffer.go          | 16 +++++++++
 pkg/tools/elf/elf.go                               |  6 ++--
 pkg/tools/process/process.go                       |  4 +++
 pkg/tools/profiling/not_support.go                 |  6 ++--
 pkg/tools/ssl/gotls.go                             | 38 +++++++++++++++++++---
 pkg/tools/ssl/openssl.go                           |  9 ++---
 pkg/tools/ssl/ssl.go                               |  2 +-
 8 files changed, 68 insertions(+), 14 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 11ff035..e66497d 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -5,6 +5,7 @@ Release Notes.
 0.6.0
 ------------------
 #### Features
+* Enhance compatibility when profiling with SSL.
 
 #### Bug Fixes
 
diff --git a/pkg/profiling/task/network/analyze/buffer/buffer.go 
b/pkg/profiling/task/network/analyze/buffer/buffer.go
index 7c60b98..8b5ed98 100644
--- a/pkg/profiling/task/network/analyze/buffer/buffer.go
+++ b/pkg/profiling/task/network/analyze/buffer/buffer.go
@@ -326,6 +326,22 @@ func (r *Buffer) ReadFromCurrent(p []byte) (element 
*list.Element, n int) {
        return element, 0
 }
 
+func (r *Buffer) Merge(other *Buffer) {
+       if other == nil {
+               return
+       }
+       for e := other.dataEvents.Front(); e != nil; e = e.Next() {
+               if v, ok := e.Value.(*events.SocketDataUploadEvent); ok && v != 
nil {
+                       r.AppendDataEvent(v)
+               }
+       }
+       for e := other.detailEvents.Front(); e != nil; e = e.Next() {
+               if v, ok := e.Value.(*events.SocketDetailEvent); ok && v != nil 
{
+                       r.AppendDetailEvent(v)
+               }
+       }
+}
+
 func (r *Buffer) read0(currentElement *list.Element, currentBuffer 
events.SocketDataBuffer, p []byte) (n int, err error) {
        readLen := len(p)
        if currentBuffer.BufferLen() < readLen {
diff --git a/pkg/tools/elf/elf.go b/pkg/tools/elf/elf.go
index b6fd466..51237ff 100644
--- a/pkg/tools/elf/elf.go
+++ b/pkg/tools/elf/elf.go
@@ -24,7 +24,7 @@ import (
 )
 
 type File struct {
-       path     string
+       Path     string
        realFile *elf.File
 }
 
@@ -40,7 +40,7 @@ func NewFile(path string) (*File, error) {
                return nil, err
        }
        return &File{
-               path:     path,
+               Path:     path,
                realFile: f,
        }, nil
 }
@@ -75,7 +75,7 @@ func (f *File) ReadSymbolData(section string, offset, size 
uint64) ([]byte, erro
        }
 
        dataOffset := offset - elfSection.Addr + elfSection.Offset
-       realFile, err := os.Open(f.path)
+       realFile, err := os.Open(f.Path)
        if err != nil {
                return nil, err
        }
diff --git a/pkg/tools/process/process.go b/pkg/tools/process/process.go
index 1186b8e..fd074a6 100644
--- a/pkg/tools/process/process.go
+++ b/pkg/tools/process/process.go
@@ -134,6 +134,10 @@ func analyzeProfilingInfo(context *analyzeContext, pid 
int32) (*profiling.Info,
 
                module, err = context.GetFinder(modulePath).ToModule(pid, 
moduleName, modulePath, []*profiling.ModuleRange{moduleRange})
                if err != nil {
+                       if err == profiling.ErrNotSupport {
+                               log.Warnf("not support the module in 
process(%d): %s, path: %s", pid, moduleName, modulePath)
+                               continue
+                       }
                        return nil, fmt.Errorf("could not init the module: %s, 
error: %v", moduleName, err)
                }
                modules[moduleName] = module
diff --git a/pkg/tools/profiling/not_support.go 
b/pkg/tools/profiling/not_support.go
index 6791c3f..565497f 100644
--- a/pkg/tools/profiling/not_support.go
+++ b/pkg/tools/profiling/not_support.go
@@ -21,6 +21,8 @@ import (
        "fmt"
 )
 
+var ErrNotSupport = fmt.Errorf("not support")
+
 type NotSupport struct {
 }
 
@@ -34,9 +36,9 @@ func (l *NotSupport) IsSupport(filePath string) bool {
 }
 
 func (l *NotSupport) AnalyzeSymbols(filePath string) ([]*Symbol, error) {
-       return nil, fmt.Errorf("not support")
+       return nil, ErrNotSupport
 }
 
 func (l *NotSupport) ToModule(pid int32, modName, modPath string, moduleRange 
[]*ModuleRange) (*Module, error) {
-       return nil, fmt.Errorf("not support")
+       return nil, ErrNotSupport
 }
diff --git a/pkg/tools/ssl/gotls.go b/pkg/tools/ssl/gotls.go
index 8a52ba8..340242b 100644
--- a/pkg/tools/ssl/gotls.go
+++ b/pkg/tools/ssl/gotls.go
@@ -21,7 +21,9 @@ import (
        "bytes"
        "encoding/binary"
        "fmt"
+       "os/exec"
        "regexp"
+       "strings"
 
        "github.com/apache/skywalking-rover/pkg/tools/elf"
        "github.com/apache/skywalking-rover/pkg/tools/host"
@@ -119,7 +121,13 @@ func (r *Register) GoTLS(symbolAddrMap *ebpf.Map, write, 
writeRet, read, readRet
        })
 }
 
-func (r *Register) getGoVersion(elfFile *elf.File, versionSymbol 
*profiling.Symbol) (*version.Version, error) {
+func (r *Register) getGoVersion(elfFile *elf.File, versionSymbol 
*profiling.Symbol) (ver *version.Version, err error) {
+       defer func() {
+               // if cannot getting version from symbol, then trying to get 
from strings command
+               if ver == nil {
+                       ver, err = r.getGoVersionByStrings(elfFile.Path)
+               }
+       }()
        buffer, err := elfFile.ReadSymbolData(".data", versionSymbol.Location, 
versionSymbol.Size)
        if err != nil {
                return nil, fmt.Errorf("reading go version struct info failure: 
%v", err)
@@ -136,11 +144,33 @@ func (r *Register) getGoVersion(elfFile *elf.File, 
versionSymbol *profiling.Symb
        }
 
        // parse versions
-       submatch := goVersionRegex.FindStringSubmatch(string(buffer))
+       if ver, ok, err := r.gettingGoVersionFromString(string(buffer)); ok {
+               return ver, err
+       }
+       return nil, fmt.Errorf("the go version is failure to identify, version: 
%s", string(buffer))
+}
+
+func (r *Register) getGoVersionByStrings(p string) (*version.Version, error) {
+       result, err := exec.Command("strings", p).Output()
+       if err != nil {
+               return nil, err
+       }
+       for _, d := range strings.Split(string(result), "\n") {
+               if v, ok, err := 
r.gettingGoVersionFromString(strings.TrimSpace(d)); ok {
+                       return v, err
+               }
+       }
+
+       return nil, fmt.Errorf("go version is not found from strings")
+}
+
+func (r *Register) gettingGoVersionFromString(s string) (v *version.Version, 
success bool, err error) {
+       submatch := goVersionRegex.FindStringSubmatch(s)
        if len(submatch) != 3 {
-               return nil, fmt.Errorf("the go version is failure to identify, 
version: %s", string(buffer))
+               return nil, false, nil
        }
-       return version.Read(submatch[1], submatch[2], "")
+       v, err = version.Read(submatch[1], submatch[2], "")
+       return v, true, err
 }
 
 type goStringInC struct {
diff --git a/pkg/tools/ssl/openssl.go b/pkg/tools/ssl/openssl.go
index 87f1931..dcd7d35 100644
--- a/pkg/tools/ssl/openssl.go
+++ b/pkg/tools/ssl/openssl.go
@@ -49,14 +49,15 @@ func (r *Register) OpenSSL(symbolAddrMap *ebpf.Map, 
sslWrite, sslWriteRet, sslRe
                if len(modules) == 0 {
                        return false, nil
                }
-               if libcrypto := modules[libcryptoName]; libcrypto != nil {
+               if libcrypto, exist := modules[libcryptoName]; exist && 
libcrypto != nil {
                        libcryptoPath = libcrypto.Path
                }
-               if libssl := modules[libsslName]; libssl != nil {
+               if libssl, exist := modules[libsslName]; exist && libssl != nil 
{
                        libsslPath = libssl.Path
                }
-               if libcryptoPath == "" || libsslPath == "" {
-                       return false, fmt.Errorf("the OpenSSL library not 
complete, libcrypto: %s, libssl: %s", libcryptoPath, libsslPath)
+               if len(modules) != 2 {
+                       log.Warnf("the OpenSSL library not complete, libcrypto: 
%s, libssl: %s", libcryptoPath, libsslPath)
+                       return false, nil
                }
 
                addresses, err := r.buildOpenSSLSymAddrConfig(libcryptoPath)
diff --git a/pkg/tools/ssl/ssl.go b/pkg/tools/ssl/ssl.go
index 4830821..f27e175 100644
--- a/pkg/tools/ssl/ssl.go
+++ b/pkg/tools/ssl/ssl.go
@@ -59,7 +59,7 @@ func (r *Register) Execute() error {
        for name, h := range r.handlers {
                b, err := h()
                if err != nil {
-                       return err
+                       return fmt.Errorf("register SSL failure, pid: %d, 
error: %v", r.pid, err)
                }
                if b {
                        count++

Reply via email to