-
Notifications
You must be signed in to change notification settings - Fork 1
ddprof Cgo test case #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # Dockerfile | ||
|
|
||
| FROM golang:1.20.5 | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| COPY ./scenarios/ddprof_go/ . | ||
|
|
||
| RUN go build main.go | ||
|
|
||
|
|
||
| RUN apt-get update && apt-get install -y \ | ||
| curl \ | ||
| xz-utils \ | ||
| jq \ | ||
| wget \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| # Install native profiling | ||
| ARG CACHE_DATE=2023-03-01_09:58:27 | ||
| COPY ./binaries/ /app/binaries/ | ||
| ADD ./profilers/ddprof/install_profiler.sh . | ||
| RUN ./install_profiler.sh /usr/local/bin | ||
|
|
||
| ENV EXECUTION_TIME="11" | ||
| # Default is that test data is dropped in the data folder | ||
| ENV DD_PROFILING_PPROF_PREFIX="/app/data/profiles_" | ||
| ENV DD_PROFILING_UPLOAD_PERIOD="10" | ||
| # One allocation of size 1000 every millisecond | ||
| CMD ["ddprof", "-l", "notice", "/app/main" ] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # Description | ||
|
|
||
| The test aims at checking that we are able to load and capture C allocations. | ||
|
|
||
| # Shortcomings | ||
|
|
||
| - We are not unwinding through the ASM CGo frame. | ||
| - The quantity of allocations is hard to predict considering the Go allocator reserves mmap regions. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| { | ||
| "test_name": "ddprof_go", | ||
| "stacks": [ | ||
| { | ||
| "profile-type": "cpu-time", | ||
| "stack-content": [ | ||
| { | ||
| "regular_expression": ";runtime\\.goexit\\.abi0;runtime\\.main;main\\.main", | ||
| "percent": 99, | ||
| "error_margin": 5, | ||
| "labels": [ | ||
| { | ||
| "key": "process_id", | ||
| "values": [ | ||
| "1" | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "profile-type": "cpu-samples", | ||
| "stack-content": [ | ||
| { | ||
| "regular_expression": ";runtime\\.goexit\\.abi0;runtime\\.main;main\\.main", | ||
| "percent": 99, | ||
| "error_margin": 3, | ||
| "labels": [ | ||
| { | ||
| "key": "process_id", | ||
| "values": [ | ||
| "1" | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "profile-type": "alloc-samples", | ||
| "stack-content": [ | ||
| { | ||
| "regular_expression": ".*runtime\\.asmcgocall\\.abi0;cAllocateMemory", | ||
| "percent": 20, | ||
| "error_margin": 40, | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't really care about the numbers (I can't predict the mmap strategy from Go), I just want them to be there. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you call this out more clearly in the README |
||
| "labels": [ | ||
| { | ||
| "key": "process_id", | ||
| "values": [ | ||
| "1" | ||
| ] | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "regular_expression": ".*;x_cgo_mmap", | ||
| "percent": 80, | ||
| "error_margin": 40, | ||
| "labels": [ | ||
| { | ||
| "key": "process_id", | ||
| "values": [ | ||
| "1" | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "os" | ||
| "runtime" | ||
| "strconv" | ||
| "time" | ||
| ) | ||
|
|
||
| /* | ||
| #include <stdio.h> | ||
| #include <stdlib.h> | ||
|
|
||
| void cAllocateMemory() { | ||
| // Allocate some memory in the C function | ||
| int size_alloc = 10000; | ||
| int* data = (int*)malloc(size_alloc * sizeof(int)); | ||
| int sum = 0; | ||
| // Use the allocated memory to avoid compiler optimizations | ||
| for (int i = 0; i < size_alloc; i++) { | ||
| data[i] = i; | ||
| } | ||
| for (int i = 0; i < size_alloc; i++) { | ||
| sum += data[i]; | ||
| } | ||
| printf("%d\n", sum); | ||
|
Comment on lines
+24
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ⛏️ indentation |
||
| // Free the allocated memory | ||
| free(data); | ||
| } | ||
| */ | ||
| import "C" | ||
|
|
||
| func burnCPU() { | ||
| // Simulate CPU-intensive work | ||
| for i := 0; i < 1000000000; i++ { | ||
| _ = i * i | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How do we guarantee this won't be optimized? |
||
| } | ||
| } | ||
|
|
||
| func allocateMemory() { | ||
| // Allocate some memory in Go | ||
| data := make([]int, 100) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason we're doing 10K in C, and 100 in Go? For future, might be interesting to make this configurable to see how we do at profiling as the relative ratios change There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not really, only that I was sure not to catch these for now, so I did not care about having smaller allocations. The native profiler can not instrument the Go allocator (only the mmaps). |
||
|
|
||
| // Use the allocated memory to avoid compiler optimizations | ||
| for i := 0; i < 100; i++ { | ||
| data[i] = i | ||
| } | ||
| } | ||
|
|
||
| func main() { | ||
| // Get the execution time from the environment variable | ||
| executionTimeStr := os.Getenv("EXECUTION_TIME") | ||
| executionTime, err := strconv.Atoi(executionTimeStr) | ||
| if err != nil { | ||
| fmt.Println("Error parsing EXECUTION_TIME:", err) | ||
| return | ||
| } | ||
|
|
||
| // Calculate the end time based on the execution time | ||
| endTime := time.Now().Add(time.Duration(executionTime) * time.Second) | ||
|
|
||
| // Run the loop until the specified duration is reached | ||
| for time.Now().Before(endTime) { | ||
| burnCPU() | ||
| allocateMemory() | ||
| C.cAllocateMemory() | ||
| time.Sleep(100 * time.Millisecond) // Sleep to simulate some delay | ||
| } | ||
|
|
||
| // Print some memory stats at the end | ||
| var m runtime.MemStats | ||
| runtime.ReadMemStats(&m) | ||
| fmt.Printf("Allocated memory (bytes): %v\n", m.Alloc) | ||
| fmt.Printf("Total memory allocated (bytes): %v\n", m.TotalAlloc) | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noob question: What does this date signify? Does it mean we're using a version from March?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a trick to force the second part of the docker to re-fetch new versions of the profiler.