Skip to content

Commit

Permalink
Allocate memory without launcher (#40)
Browse files Browse the repository at this point in the history
* Allocate memory without launcher

* remove findKeyvalMap func

* fix makefile: enable CGO

* fix Dockerfile

* code review comments

* remove launcher from e2e tests

* Update Makefile

Co-authored-by: Mike Goldsmith <goldsmith.mike@gmail.com>

* rename Addr to StartAddr

* rollback uname change

* removed by mistake

---------

Co-authored-by: Mike Dame <mikedame@google.com>
Co-authored-by: Mike Goldsmith <goldsmith.mike@gmail.com>
  • Loading branch information
3 people committed Apr 11, 2023
1 parent 3b71cac commit 859307d
Show file tree
Hide file tree
Showing 10 changed files with 513 additions and 53 deletions.
22 changes: 1 addition & 21 deletions .github/workflows/e2e/k8s/sample-job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,13 @@ spec:
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
initContainers:
- name: copy-launcher
image: kv-launcher
imagePullPolicy: IfNotPresent
command:
- cp
- -a
- /kv-launcher/.
- /launcher/
volumeMounts:
- name: launcherdir
mountPath: /launcher

containers:
- name: sample-app
image: sample-app
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c"]
# send SIGTERM to otel-go-instrumentation once the sample app has generated data so the job completes.
args: ["/launcher/launch /sample-app/main && kill -TERM $(pidof otel-go-instrumentation)"]
volumeMounts:
- mountPath: /launcher
name: launcherdir

args: ["/sample-app/main && kill -TERM $(pidof otel-go-instrumentation)"]
- name: auto-instrumentation
image: otel-go-instrumentation
imagePullPolicy: IfNotPresent
Expand All @@ -62,10 +45,7 @@ spec:
volumeMounts:
- mountPath: /sys/kernel/debug
name: kernel-debug

volumes:
- name: launcherdir
emptyDir: {}
- name: kernel-debug
hostPath:
path: /sys/kernel/debug
6 changes: 0 additions & 6 deletions .github/workflows/kind.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ jobs:
- name: Build auto-instrumentation
run: |
IMG=otel-go-instrumentation:latest make docker-build
- name: Build launcher #TODO: Remove launcher steps once pr/40 merges
run: |
git clone https://github.com/keyval-dev/launcher.git
cd launcher
docker build -t kv-launcher:latest .
- name: Build sample app
run: |
cd test/e2e/${{ matrix.library }}
Expand All @@ -51,7 +46,6 @@ jobs:
- name: Kind load images
run: |
kind load docker-image otel-go-instrumentation --name chart-testing
kind load docker-image kv-launcher --name chart-testing
kind load docker-image sample-app --name chart-testing
- name: Add Dependencies
shell: bash
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ WORKDIR /app
COPY . .
RUN make build

FROM gcr.io/distroless/base-debian11
FROM registry.fedoraproject.org/fedora-minimal:35
COPY --from=builder /app/otel-go-instrumentation /
CMD ["/otel-go-instrumentation"]
8 changes: 2 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ generate:

.PHONY: build
build: generate
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o otel-go-instrumentation cli/main.go
GOOS=linux GOARCH=amd64 go build -o otel-go-instrumentation cli/main.go

.PHONY: docker-build
docker-build:
Expand Down Expand Up @@ -69,13 +69,9 @@ fixture-gorillamux: fixtures/gorillamux
fixtures/%: LIBRARY=$*
fixtures/%:
IMG=otel-go-instrumentation $(MAKE) docker-build
if [ ! -d "launcher" ]; then \
git clone https://github.com/keyval-dev/launcher.git; \
fi
cd launcher && docker build -t kv-launcher .
cd test/e2e/$(LIBRARY) && docker build -t sample-app .
kind create cluster
kind load docker-image otel-go-instrumentation sample-app kv-launcher
kind load docker-image otel-go-instrumentation sample-app
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
if [ ! -d "opentelemetry-helm-charts" ]; then \
git clone https://github.com/open-telemetry/opentelemetry-helm-charts.git; \
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/go-logr/logr v1.2.4
github.com/go-logr/zapr v1.2.3
github.com/hashicorp/go-version v1.6.0
github.com/pkg/errors v0.9.1
github.com/prometheus/procfs v0.9.0
go.opentelemetry.io/otel v1.14.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0
Expand Down
52 changes: 33 additions & 19 deletions pkg/process/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ import (
"os"
"strings"

"github.com/prometheus/procfs"

"github.com/hashicorp/go-version"
"github.com/open-telemetry/opentelemetry-go-instrumentation/pkg/log"
"github.com/open-telemetry/opentelemetry-go-instrumentation/pkg/process/ptrace"
"golang.org/x/arch/x86/x86asm"
)

const (
mapSize = 15 * 1024 * 1024
)

type TargetDetails struct {
PID int
Functions []*Func
Expand Down Expand Up @@ -73,28 +76,28 @@ func (t *TargetDetails) GetFunctionReturns(name string) ([]uint64, error) {
return nil, fmt.Errorf("could not find returns for function %s", name)
}

func findKeyvalMmap(pid int) *AllocationDetails {
fs, err := procfs.NewProc(pid)
func (a *processAnalyzer) remoteMmap(pid int, mapSize uint64) (uint64, error) {
program, err := ptrace.NewTracedProgram(pid, log.Logger)
if err != nil {
panic(err)
log.Logger.Error(err, "Failed to attach ptrace", "pid", pid)
return 0, err
}

maps, err := fs.ProcMaps()
defer func() {
log.Logger.V(0).Info("Detaching from process", "pid", pid)
err := program.Detach()
if err != nil {
log.Logger.Error(err, "Failed to detach ptrace", "pid", pid)
}
}()
fd := -1
addr, err := program.Mmap(mapSize, uint64(fd))
if err != nil {
panic(err)
log.Logger.Error(err, "Failed to mmap", "pid", pid)
return 0, err
}

for _, m := range maps {
if m.Perms != nil && m.Perms.Read && m.Perms.Write && m.Perms.Execute {
log.Logger.Info("found addr of keyval map", "addr", m.StartAddr)
return &AllocationDetails{
StartAddr: uint64(m.StartAddr),
EndAddr: uint64(m.EndAddr),
}
}
}
log.Logger.V(1).Info("could not allocate remote memory, automatic context propagation will be disabled")
return nil
return addr, nil
}

func (a *processAnalyzer) Analyze(pid int, relevantFuncs map[string]interface{}) (*TargetDetails, error) {
Expand All @@ -120,7 +123,18 @@ func (a *processAnalyzer) Analyze(pid int, relevantFuncs map[string]interface{})
result.GoVersion = goVersion
result.Libraries = modules

result.AllocationDetails = findKeyvalMmap(pid)
addr, err := a.remoteMmap(pid, mapSize)
if err != nil {
log.Logger.Error(err, "Failed to mmap")
return nil, err
}
log.Logger.V(0).Info("mmaped remote memory", "start_addr", fmt.Sprintf("%X", addr),
"end_addr", fmt.Sprintf("%X", addr+mapSize))

result.AllocationDetails = &AllocationDetails{
StartAddr: addr,
EndAddr: addr + mapSize,
}

var pclndat []byte
if sec := elfF.Section(".gopclntab"); sec != nil {
Expand Down
29 changes: 29 additions & 0 deletions pkg/process/ptrace/cwrapper_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// 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.

//go:build cgo

package ptrace

/*
#define _GNU_SOURCE
#include <sys/wait.h>
#include <sys/uio.h>
#include <errno.h>
*/
import "C"

func waitpid(pid int) int {
return int(C.waitpid(C.int(pid), nil, C.__WALL))
}
Loading

0 comments on commit 859307d

Please sign in to comment.