Skip to content

Commit 23d540a

Browse files
authored
Merge branch 'main' into imp_tracing
2 parents 3c8d8aa + d969183 commit 23d540a

File tree

23 files changed

+208
-82
lines changed

23 files changed

+208
-82
lines changed

.github/workflows/codeql-analysis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ jobs:
6767

6868
# Initializes the CodeQL tools for scanning.
6969
- name: Initialize CodeQL
70-
uses: github/codeql-action/init@004c5de30b6423267685b897a3d595e944f7fed5 # v2.20.2
70+
uses: github/codeql-action/init@489225d82a57396c6f426a40e66d461b16b3461d # v2.20.4
7171
with:
7272
languages: ${{ matrix.language }}
7373
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -86,4 +86,4 @@ jobs:
8686
- run: make build
8787

8888
- name: Perform CodeQL Analysis
89-
uses: github/codeql-action/analyze@004c5de30b6423267685b897a3d595e944f7fed5 # v2.20.2
89+
uses: github/codeql-action/analyze@489225d82a57396c6f426a40e66d461b16b3461d # v2.20.4

.github/workflows/container.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ on:
1212

1313
env:
1414
# renovate: datasource=go depName=github.com/goreleaser/goreleaser
15-
GORELEASER_VERSION: v1.18.2
15+
GORELEASER_VERSION: v1.19.2
1616
# renovate: datasource=github-releases depName=kubernetes/minikube extractVersion=^v(?<version>.+)$
1717
MINIKUBE_VERSION: 1.30.1
1818

@@ -104,7 +104,7 @@ jobs:
104104
runs-on: ubuntu-latest
105105
needs: build-dependencies
106106
container:
107-
image: docker.io/goreleaser/goreleaser-cross:v1.20.5
107+
image: docker.io/goreleaser/goreleaser-cross:v1.20.6@sha256:ed6790d7eab29875321ce68a09aaedb42c3bcbde8525b0916bd4601d31157c1b
108108
options: --privileged
109109
env:
110110
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ permissions:
1010

1111
env:
1212
# renovate: datasource=go depName=github.com/goreleaser/goreleaser
13-
GORELEASER_VERSION: v1.18.2
13+
GORELEASER_VERSION: v1.19.2
1414

1515
jobs:
1616
dependencies:
@@ -55,7 +55,7 @@ jobs:
5555
needs: dependencies
5656
if: startsWith(github.ref, 'refs/tags/')
5757
container:
58-
image: docker.io/goreleaser/goreleaser-cross:v1.20.5
58+
image: docker.io/goreleaser/goreleaser-cross:v1.20.6@sha256:ed6790d7eab29875321ce68a09aaedb42c3bcbde8525b0916bd4601d31157c1b
5959
options: --privileged
6060
env:
6161
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/snap.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ on:
1212

1313
env:
1414
# renovate: datasource=go depName=github.com/goreleaser/goreleaser
15-
GORELEASER_VERSION: v1.18.2
15+
GORELEASER_VERSION: v1.19.2
1616

1717
permissions:
1818
contents: write
@@ -85,7 +85,7 @@ jobs:
8585
runs-on: ubuntu-latest
8686
needs: dependencies
8787
container:
88-
image: docker.io/goreleaser/goreleaser-cross:v1.20.5
88+
image: docker.io/goreleaser/goreleaser-cross:v1.20.6@sha256:ed6790d7eab29875321ce68a09aaedb42c3bcbde8525b0916bd4601d31157c1b
8989
options: --privileged
9090
env:
9191
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.go-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.20.5
1+
1.20.6

.goreleaser.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ archives:
8888
format_overrides:
8989
- goos: windows
9090
format: zip
91-
rlcp: true # This can be removed once it's the default behavior
9291
files:
9392
- 'LICENSE*'
9493
- 'README*'

Dockerfile.dev

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# hadolint ignore=DL3029
2-
FROM --platform="${BUILDPLATFORM:-linux/amd64}" docker.io/goreleaser/goreleaser-cross:v1.20.5@sha256:e222cdc070aa5087e09ed3917ef1e4de6123c8a0cb36d7b40c8d0e46b8cc53ae AS builder
2+
FROM --platform="${BUILDPLATFORM:-linux/amd64}" docker.io/goreleaser/goreleaser-cross:v1.20.6@sha256:ed6790d7eab29875321ce68a09aaedb42c3bcbde8525b0916bd4601d31157c1b AS builder
33

44
# hadolint ignore=DL3008
55
RUN apt-get update -y --no-install-recommends && \

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ endif
4040
VERSION ?= $(if $(RELEASE_TAG),$(RELEASE_TAG),$(shell $(CMD_GIT) describe --tags || echo '$(subst /,-,$(BRANCH))$(COMMIT_TIMESTAMP)$(COMMIT)'))
4141

4242
# renovate: datasource=docker depName=docker.io/goreleaser/goreleaser-cross
43-
GOLANG_CROSS_VERSION := v1.20.5
43+
GOLANG_CROSS_VERSION := v1.20.6
4444

4545
# inputs and outputs:
4646
OUT_DIR ?= dist

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ Flags:
6060
--log-level="info" Log level.
6161
--log-format="logfmt" Configure if structured logging as JSON or as
6262
logfmt
63-
--http-address=":7071" Address to bind HTTP server to.
63+
--http-address="127.0.0.1:7071"
64+
Address to bind HTTP server to.
6465
--version Show application version.
6566
--node="hostname" The name of the node that the process is
6667
running on. If on Kubernetes, this must match

bpf/cpu/cpu.bpf.c

Lines changed: 61 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
// Copyright 2022 The Parca Authors
77

88
#include <common.h>
9-
#include <vmlinux.h>
109
#include <hash.h>
10+
#include <vmlinux.h>
1111

1212
#include <bpf/bpf_core_read.h>
1313
#include <bpf/bpf_endian.h>
@@ -97,7 +97,15 @@ struct unwinder_stats_t {
9797
u64 error_catchall;
9898
u64 error_should_never_happen;
9999
u64 error_pc_not_covered;
100-
u64 error_jit;
100+
u64 error_pc_not_covered_jit;
101+
u64 error_jit_unupdated_mapping;
102+
u64 error_jit_mixed_mode_disabled; // JIT error because mixed-mode unwinding is disabled
103+
u64 error_jit_unwinding_machinery;
104+
u64 success_jit_frame;
105+
u64 success_jit_to_dwarf;
106+
u64 success_dwarf_to_jit;
107+
u64 success_dwarf_reach_bottom;
108+
u64 success_jit_reach_bottom;
101109
};
102110

103111
const volatile struct unwinder_config_t unwinder_config = {};
@@ -157,7 +165,7 @@ typedef struct {
157165

158166
typedef struct {
159167
int pid;
160-
int tgid;
168+
int tid;
161169
int user_stack_id;
162170
int kernel_stack_id;
163171
int user_stack_id_dwarf;
@@ -267,7 +275,15 @@ DEFINE_COUNTER(error_unsupported_cfa_register);
267275
DEFINE_COUNTER(error_catchall);
268276
DEFINE_COUNTER(error_should_never_happen);
269277
DEFINE_COUNTER(error_pc_not_covered);
270-
DEFINE_COUNTER(error_jit);
278+
DEFINE_COUNTER(error_pc_not_covered_jit);
279+
DEFINE_COUNTER(error_jit_unwinding_machinery);
280+
DEFINE_COUNTER(error_jit_unupdated_mapping);
281+
DEFINE_COUNTER(error_jit_mixed_mode_disabled);
282+
DEFINE_COUNTER(success_jit_frame);
283+
DEFINE_COUNTER(success_jit_to_dwarf);
284+
DEFINE_COUNTER(success_dwarf_to_jit);
285+
DEFINE_COUNTER(success_dwarf_reach_bottom);
286+
DEFINE_COUNTER(success_jit_reach_bottom);
271287

272288
static void unwind_print_stats() {
273289
// Do not use the LOG macro, always print the stats.
@@ -285,9 +301,17 @@ static void unwind_print_stats() {
285301
bpf_printk("\tunsup_cfa_reg=%lu", unwinder_stats->error_unsupported_cfa_register);
286302
bpf_printk("\tcatchall=%lu", unwinder_stats->error_catchall);
287303
bpf_printk("\tnever=%lu", unwinder_stats->error_should_never_happen);
288-
bpf_printk("\tunsup_jit=%lu", unwinder_stats->error_jit);
304+
bpf_printk("\terror_jit_unwinding_machinery=%lu", unwinder_stats->error_jit_unwinding_machinery);
305+
bpf_printk("\tunsup_jit=%lu", unwinder_stats->error_jit_unupdated_mapping);
306+
bpf_printk("\tunsup_jit_mixed_mode_disabled=%lu", unwinder_stats->error_jit_mixed_mode_disabled);
307+
bpf_printk("\tjit_frame=%lu", unwinder_stats->success_jit_frame);
308+
bpf_printk("\tjit_to_dwarf_switch=%lu", unwinder_stats->success_jit_to_dwarf);
309+
bpf_printk("\tdwarf_to_jit_switch=%lu", unwinder_stats->success_dwarf_to_jit);
310+
bpf_printk("\treached_bottom_frame_dwarf=%lu", unwinder_stats->success_dwarf_reach_bottom);
311+
bpf_printk("\treached_bottom_frame_jit=%lu", unwinder_stats->success_jit_reach_bottom);
289312
bpf_printk("\ttotal_counter=%lu", unwinder_stats->total);
290313
bpf_printk("\t(not_covered=%lu)", unwinder_stats->error_pc_not_covered);
314+
bpf_printk("\t(not_covered_jit=%lu)", unwinder_stats->error_pc_not_covered_jit);
291315
bpf_printk("");
292316
}
293317

@@ -608,11 +632,16 @@ static __always_inline void add_stack(struct bpf_perf_event_data *ctx, u64 pid_t
608632
// mean different things in kernel and user space.
609633
//
610634
// - What we call PIDs in userspace, are TGIDs in kernel space.
611-
// - What we call threads IDs in user space, are PIDs in kernel space.
635+
// - What we call **thread IDs** in user space, are PIDs in kernel space.
636+
// In other words, the process ID in the lower 32 bits (kernel's view of the PID,
637+
// which in user space is usually presented as the thread ID),
638+
// and the thread group ID in the upper 32 bits
639+
// (what user space often thinks of as the PID).
640+
612641
int user_pid = pid_tgid >> 32;
613642
int user_tgid = pid_tgid;
614643
stack_key.pid = user_pid;
615-
stack_key.tgid = user_tgid;
644+
stack_key.tid = user_tgid;
616645

617646
if (method == STACK_WALKING_METHOD_DWARF) {
618647
int stack_hash = MurmurHash2((u32 *)unwind_state->stack.addresses, MAX_STACK_DEPTH * sizeof(u64) / sizeof(u32), 0);
@@ -664,6 +693,8 @@ int walk_user_stacktrace_impl(struct bpf_perf_event_data *ctx) {
664693
bool reached_bottom_of_stack = false;
665694
u64 zero = 0;
666695

696+
bool dwarf_to_jit = false;
697+
667698
unwind_state_t *unwind_state = bpf_map_lookup_elem(&heap, &zero);
668699
if (unwind_state == NULL) {
669700
LOG("unwind_state is NULL, should not happen");
@@ -686,12 +717,17 @@ int walk_user_stacktrace_impl(struct bpf_perf_event_data *ctx) {
686717
if (unwind_table_result == FIND_UNWIND_JITTED) {
687718
if (!unwinder_config.mixed_stack_enabled) {
688719
LOG("JIT section, stopping. Please enable mixed-mode unwinding with the --dwarf-unwinding-mixed=true to profile JITed stacks.");
720+
bump_unwind_error_jit_mixed_mode_disabled();
689721
return 1;
690722
}
691723

692724
LOG("[debug] Unwinding JITed stacks");
693725

694726
unwind_state->unwinding_jit = true;
727+
if (dwarf_to_jit) {
728+
dwarf_to_jit = false;
729+
bump_unwind_success_dwarf_to_jit();
730+
}
695731

696732
u64 next_fp = 0;
697733
u64 ra = 0;
@@ -733,6 +769,7 @@ int walk_user_stacktrace_impl(struct bpf_perf_event_data *ctx) {
733769

734770
if (next_fp == 0) {
735771
LOG("[info] found bottom frame while walking JITed section");
772+
bump_unwind_success_jit_reach_bottom();
736773
return 1;
737774
}
738775

@@ -746,6 +783,7 @@ int walk_user_stacktrace_impl(struct bpf_perf_event_data *ctx) {
746783
if (len >= 0 && len < MAX_STACK_DEPTH) {
747784
unwind_state->stack.addresses[len] = ra;
748785
unwind_state->stack.len++;
786+
bump_unwind_success_jit_frame();
749787
}
750788

751789
continue;
@@ -799,17 +837,17 @@ int walk_user_stacktrace_impl(struct bpf_perf_event_data *ctx) {
799837
if (found_cfa_type == CFA_TYPE_END_OF_FDE_MARKER) {
800838
LOG("[info] PC %llx not contained in the unwind info, found marker", unwind_state->ip);
801839
reached_bottom_of_stack = true;
840+
bump_unwind_success_dwarf_reach_bottom(); // assuming we only have unwind tables for DWARF frames, not FP or JIT frames
802841
break;
803842
}
804843

805844
if (found_rbp_type == RBP_TYPE_UNDEFINED_RETURN_ADDRESS) {
806845
LOG("[info] null return address, end of stack", unwind_state->ip);
807846
reached_bottom_of_stack = true;
847+
bump_unwind_success_dwarf_reach_bottom();
808848
break;
809849
}
810850

811-
LOG("[debug] Switching to mixed-mode unwinding");
812-
813851
// Add address to stack.
814852
u64 len = unwind_state->stack.len;
815853
// Appease the verifier.
@@ -827,7 +865,8 @@ int walk_user_stacktrace_impl(struct bpf_perf_event_data *ctx) {
827865
}
828866

829867
// Set unwind_state->unwinding_jit to false once we have checked for switch from JITed unwinding to DWARF unwinding
830-
if(unwind_state->unwinding_jit) {
868+
if (unwind_state->unwinding_jit) {
869+
bump_unwind_success_jit_to_dwarf();
831870
LOG("[debug] Switched to mixed-mode DWARF unwinding");
832871
}
833872
unwind_state->unwinding_jit = false;
@@ -898,7 +937,7 @@ int walk_user_stacktrace_impl(struct bpf_perf_event_data *ctx) {
898937
LOG("[warn] mapping not added yet");
899938
request_refresh_process_info(ctx, user_pid);
900939

901-
bump_unwind_error_jit();
940+
bump_unwind_error_jit_unupdated_mapping();
902941
return 1;
903942
}
904943

@@ -952,6 +991,8 @@ int walk_user_stacktrace_impl(struct bpf_perf_event_data *ctx) {
952991
LOG("======= reached main! =======");
953992
add_stack(ctx, pid_tgid, STACK_WALKING_METHOD_DWARF, unwind_state);
954993
bump_unwind_success_dwarf();
994+
// success_dwarf_to_jit keeps track of transition from DWARF unwinding to JIT unwinding
995+
dwarf_to_jit = true;
955996
} else {
956997
int user_pid = pid_tgid;
957998
process_info_t *proc_info = bpf_map_lookup_elem(&process_info, &user_pid);
@@ -961,9 +1002,10 @@ int walk_user_stacktrace_impl(struct bpf_perf_event_data *ctx) {
9611002
}
9621003

9631004
if (proc_info->is_jit_compiler) {
964-
LOG("[warn] mapping not added yet rbp %llx", unwind_state->bp);
1005+
LOG("[warn] mapping not added yet to BPF maps, rbp %llx", unwind_state->bp);
9651006
request_refresh_process_info(ctx, user_pid);
966-
bump_unwind_error_jit();
1007+
bump_unwind_error_jit_unupdated_mapping(); // rbp != 0 and we are expecting unwind info which is absent and not expecting JITed stacks and therefore are
1008+
// not symbolising JITed stacks here but maybe it's a JIT stack
9671009
return 1;
9681010
}
9691011

@@ -1063,7 +1105,6 @@ int profile_cpu(struct bpf_perf_event_data *ctx) {
10631105
return 0;
10641106
}
10651107

1066-
10671108
// 1. If we have unwind information for a process, use it.
10681109
if (has_unwind_information(user_pid)) {
10691110
bump_samples();
@@ -1083,18 +1124,18 @@ int profile_cpu(struct bpf_perf_event_data *ctx) {
10831124
bump_unwind_error_pc_not_covered();
10841125
return 1;
10851126
} else if (unwind_table_result == FIND_UNWIND_JITTED) {
1086-
1087-
10881127
if (!unwinder_config.mixed_stack_enabled) {
1089-
LOG("[warn] IP 0x%llx not covered, JIT (but disabled)!.", unwind_state->ip);
1090-
bump_unwind_error_jit();
1128+
LOG("[warn] IP 0x%llx not covered, JIT (but mixed-mode unwinding disabled)!.", unwind_state->ip);
1129+
bump_unwind_error_pc_not_covered_jit();
1130+
bump_unwind_error_jit_mixed_mode_disabled();
10911131
return 1;
10921132
}
10931133
} else if (proc_info->is_jit_compiler) {
10941134
LOG("[warn] IP 0x%llx not covered, may be JIT!.", unwind_state->ip);
10951135
request_refresh_process_info(ctx, user_pid);
1096-
// We assume this failed because of a new JIT segment.
1097-
bump_unwind_error_jit();
1136+
bump_unwind_error_pc_not_covered_jit();
1137+
// We assume this failed because of a new JIT segment so we refresh mappings to find JIT segment in updated mappings
1138+
bump_unwind_error_jit_unupdated_mapping();
10981139
return 1;
10991140
}
11001141
}

0 commit comments

Comments
 (0)