This is an automated email from the ASF dual-hosted git repository.
liuhan 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 c0cf80d Support build multiple architecture docker image: `x86_64`,
`arm64` (#83)
c0cf80d is described below
commit c0cf80d5ed01ffa4117cebedb082bfeadcec5b57
Author: mrproliu <[email protected]>
AuthorDate: Thu Mar 23 18:13:51 2023 +0800
Support build multiple architecture docker image: `x86_64`, `arm64` (#83)
---
.github/workflows/rover.yaml | 6 +-
CHANGES.md | 1 +
bpf/include/api.h | 8 +-
bpf/include/goid.h | 10 +-
bpf/include/symbol_offsets.h | 35 +++++--
bpf/include/syscall_reading.h | 34 +++++++
bpf/profiling/continuous/network.c | 1 +
bpf/profiling/network/netmonitor.c | 110 ++++++++-------------
docker/Dockerfile.base | 6 +-
docker/Dockerfile.build | 2 +-
.../continuous/checker/bpf/network/network.go | 2 +-
.../analyze/layer7/protocols/base/buffer.go | 2 +-
pkg/profiling/task/network/bpf/bpf.go | 2 +-
pkg/profiling/task/offcpu/runner.go | 2 +-
pkg/tools/btf/linker.go | 33 +++++--
pkg/tools/elf/abi.go | 6 +-
scripts/build/base.mk | 19 +++-
scripts/build/btf.mk | 8 +-
scripts/build/build.mk | 8 +-
scripts/build/docker.mk | 23 +++--
scripts/build/generate.mk | 2 +-
21 files changed, 205 insertions(+), 115 deletions(-)
diff --git a/.github/workflows/rover.yaml b/.github/workflows/rover.yaml
index dbb60e0..ab504b0 100644
--- a/.github/workflows/rover.yaml
+++ b/.github/workflows/rover.yaml
@@ -23,7 +23,7 @@ jobs:
build:
name: Build and Test
runs-on: ubuntu-latest
- timeout-minutes: 30
+ timeout-minutes: 60
steps:
- name: Set up Go 1.18
uses: actions/setup-go@v2
@@ -51,7 +51,7 @@ jobs:
docker:
name: Docker images
runs-on: ubuntu-latest
- timeout-minutes: 30
+ timeout-minutes: 60
steps:
- uses: actions/checkout@v2
with:
@@ -209,4 +209,4 @@ jobs:
fi
if [[ ${{ needs.https-e2e-test.result }} != 'success' ]]; then
exit -1
- fi
\ No newline at end of file
+ fi
diff --git a/CHANGES.md b/CHANGES.md
index 82cc739..8b8164d 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -11,6 +11,7 @@ Release Notes.
* Optimized the data structure in BPF.
* Support continuous profiling.
* Improve the performance when getting `goid` in eBPF.
+* Support build multiple architecture docker image: `x86_64`, `arm64`.
#### Bug Fixes
* Fix HTTP method name in protocol analyzer
diff --git a/bpf/include/api.h b/bpf/include/api.h
index fa4aa16..0d76451 100644
--- a/bpf/include/api.h
+++ b/bpf/include/api.h
@@ -47,8 +47,14 @@ typedef enum
} bool;
struct thread_struct {
+ // x86_64
long unsigned int fsbase;
-} __attribute__((preserve_access_index));
+ // arm64
+ struct {
+ unsigned long tp_value; /* TLS register */
+ unsigned long tp2_value;
+ } uw;
+} __attribute__((preserve_access_index));
struct task_struct {
__u32 pid;
diff --git a/bpf/include/goid.h b/bpf/include/goid.h
index 92f0598..4d8b36e 100644
--- a/bpf/include/goid.h
+++ b/bpf/include/goid.h
@@ -39,14 +39,22 @@ static __inline __u64 get_goid(__u64 id) {
return 0;
}
+ __u64 g_addr;
+#if defined(bpf_target_x86)
// thread local storage
const void* fs_base;
bpf_probe_read_kernel(&fs_base, sizeof(fs_base),
&(task_ptr->thread.fsbase));
- __u64 g_addr;
// struct g location
int32_t g_addr_offset = -8;
bpf_probe_read_user(&g_addr, sizeof(void*), (void*)(fs_base +
g_addr_offset));
+#else
+ const void* tp;
+ bpf_probe_read_kernel(&tp, sizeof(tp), &(task_ptr->thread.uw.tp_value));
+
+ int32_t g_addr_offset = 16;
+ bpf_probe_read_user(&g_addr, sizeof(void*), (void*)(tp + g_addr_offset));
+#endif
// goid in struct g
__u64 goid;
diff --git a/bpf/include/symbol_offsets.h b/bpf/include/symbol_offsets.h
index 798b40c..805e76e 100644
--- a/bpf/include/symbol_offsets.h
+++ b/bpf/include/symbol_offsets.h
@@ -55,24 +55,39 @@ struct {
__type(value, struct go_regabi_regs_t);
__uint(max_entries, 1);
} go_regabi_regs_map SEC(".maps");
+
// Copies the registers of the golang ABI, so that they can be
// easily accessed using an offset.
-static __always_inline __u64* go_regabi_regs(const struct pt_regs* ctx) {
+static __always_inline __u64* go_regabi_regs(const void* ctx) {
__u32 zero = 0;
struct go_regabi_regs_t* regs_heap_var =
bpf_map_lookup_elem(&go_regabi_regs_map, &zero);
if (regs_heap_var == NULL) {
return NULL;
}
- regs_heap_var->regs[0] = ctx->rax;
- regs_heap_var->regs[1] = ctx->rbx;
- regs_heap_var->regs[2] = ctx->rcx;
- regs_heap_var->regs[3] = ctx->rdi;
- regs_heap_var->regs[4] = ctx->rsi;
- regs_heap_var->regs[5] = ctx->r8;
- regs_heap_var->regs[6] = ctx->r9;
- regs_heap_var->regs[7] = ctx->r10;
- regs_heap_var->regs[8] = ctx->r11;
+#if defined(bpf_target_x86)
+ const struct pt_regs* real = ctx;
+ regs_heap_var->regs[0] = real->rax;
+ regs_heap_var->regs[1] = real->rbx;
+ regs_heap_var->regs[2] = real->rcx;
+ regs_heap_var->regs[3] = real->rdi;
+ regs_heap_var->regs[4] = real->rsi;
+ regs_heap_var->regs[5] = real->r8;
+ regs_heap_var->regs[6] = real->r9;
+ regs_heap_var->regs[7] = real->r10;
+ regs_heap_var->regs[8] = real->r11;
+#else
+ const struct user_pt_regs* real = ctx;
+ regs_heap_var->regs[0] = real->regs[0];
+ regs_heap_var->regs[1] = real->regs[1];
+ regs_heap_var->regs[2] = real->regs[2];
+ regs_heap_var->regs[3] = real->regs[3];
+ regs_heap_var->regs[4] = real->regs[4];
+ regs_heap_var->regs[5] = real->regs[5];
+ regs_heap_var->regs[6] = real->regs[6];
+ regs_heap_var->regs[7] = real->regs[7];
+ regs_heap_var->regs[8] = real->regs[8];
+#endif
return regs_heap_var->regs;
}
diff --git a/bpf/include/syscall_reading.h b/bpf/include/syscall_reading.h
new file mode 100644
index 0000000..ce56b49
--- /dev/null
+++ b/bpf/include/syscall_reading.h
@@ -0,0 +1,34 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+#pragma once
+
+#include "api.h"
+
+#if defined(bpf_target_x86)
+#define SYSCALL_PARM_1(x) (_(PT_REGS_PARM1((struct pt_regs
*)PT_REGS_PARM1(x))))
+#define SYSCALL_PARM_2(x) (_(PT_REGS_PARM2((struct pt_regs
*)PT_REGS_PARM1(x))))
+#define SYSCALL_PARM_3(x) (_(PT_REGS_PARM3((struct pt_regs
*)PT_REGS_PARM1(x))))
+#define SYSCALL_PARM_4(x) (_(PT_REGS_PARM4((struct pt_regs
*)PT_REGS_PARM1(x))))
+#define SYSCALL_PARM_5(x) (_(PT_REGS_PARM5((struct pt_regs
*)PT_REGS_PARM1(x))))
+#else
+#define SYSCALL_PARM_1(x) ({__u64 val; bpf_probe_read(&val, sizeof(val), (void
*)PT_REGS_PARM1(x)); val;})
+#define SYSCALL_PARM_2(x) ({__u64 val; bpf_probe_read(&val, sizeof(val), (void
*)PT_REGS_PARM2(x)); val;})
+#define SYSCALL_PARM_3(x) ({__u64 val; bpf_probe_read(&val, sizeof(val), (void
*)PT_REGS_PARM3(x)); val;})
+#define SYSCALL_PARM_4(x) ({__u64 val; bpf_probe_read(&val, sizeof(val), (void
*)PT_REGS_PARM4(x)); val;})
+#define SYSCALL_PARM_5(x) ({__u64 val; bpf_probe_read(&val, sizeof(val), (void
*)PT_REGS_PARM5(x)); val;})
+#endif
\ No newline at end of file
diff --git a/bpf/profiling/continuous/network.c
b/bpf/profiling/continuous/network.c
index c37bdfc..b4591aa 100644
--- a/bpf/profiling/continuous/network.c
+++ b/bpf/profiling/continuous/network.c
@@ -21,6 +21,7 @@
#include <linux/sched.h>
#include <linux/bpf.h>
#include <linux/ptrace.h>
+#include <asm/ptrace.h>
#include <asm/errno.h>
#include <asm/socket.h>
#include <linux/netfilter_ipv4.h>
diff --git a/bpf/profiling/network/netmonitor.c
b/bpf/profiling/network/netmonitor.c
index 1636cea..a8c1489 100644
--- a/bpf/profiling/network/netmonitor.c
+++ b/bpf/profiling/network/netmonitor.c
@@ -31,6 +31,7 @@
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
+#include "syscall_reading.h"
#include "common.h"
#include "socket.h"
#include "sock_stats.h"
@@ -500,12 +501,11 @@ static __inline void process_connect(struct pt_regs *ctx,
__u64 id, struct conne
SEC("kprobe/connect")
int sys_connect(struct pt_regs *ctx) {
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
uint64_t id = bpf_get_current_pid_tgid();
struct connect_args_t connect_args = {};
- connect_args.fd = _(PT_REGS_PARM1(ctx));
- bpf_probe_read(&connect_args.addr, sizeof(connect_args.addr),
&(PT_REGS_PARM2(ctx)));
+ connect_args.fd = SYSCALL_PARM_1(ctx);
+ connect_args.addr = (void *)SYSCALL_PARM_2(ctx);
connect_args.start_nacs = bpf_ktime_get_ns();
bpf_map_update_elem(&conecting_args, &id, &connect_args, 0);
return 0;
@@ -547,11 +547,9 @@ static __inline void process_accept(struct pt_regs *ctx,
__u64 id, struct accept
SEC("kprobe/sys_accept")
int sys_accept(struct pt_regs *ctx) {
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
__u64 id = bpf_get_current_pid_tgid();
struct accept_args_t sock = {};
-// sock.addr = (void *)PT_REGS_PARM2(ctx);
- bpf_probe_read(&sock.addr, sizeof(sock.addr), &(PT_REGS_PARM2(ctx)));
+ sock.addr = (void *)SYSCALL_PARM_2(ctx);
sock.start_nacs = bpf_ktime_get_ns();
bpf_map_update_elem(&accepting_args, &id, &sock, 0);
return 0;
@@ -586,13 +584,10 @@ int sys_sendto(struct pt_regs *ctx) {
if (tgid_should_trace(tgid) == false) {
return 0;
}
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
- __u32 fd = _(PT_REGS_PARM1(ctx));
- char* buf;
- bpf_probe_read(&buf, sizeof(buf), &(PT_REGS_PARM2(ctx)));
+ __u32 fd = SYSCALL_PARM_1(ctx);
+ char* buf = (void *)SYSCALL_PARM_2(ctx);
- struct sockaddr* sockaddr;
- bpf_probe_read(&sockaddr, sizeof(sockaddr), &(PT_REGS_PARM5(ctx)));
+ struct sockaddr* sockaddr = (void *)SYSCALL_PARM_5(ctx);
if (sockaddr != NULL) {
struct connect_args_t connect_args = {};
connect_args.addr = sockaddr;
@@ -654,12 +649,10 @@ int sys_write(struct pt_regs *ctx) {
if (tgid_should_trace(tgid) == false) {
return 0;
}
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
- char* buf;
- bpf_probe_read(&buf, sizeof(buf), &(PT_REGS_PARM2(ctx)));
+ char* buf = (void *)SYSCALL_PARM_2(ctx);
struct sock_data_args_t data_args = {};
- data_args.fd = _(PT_REGS_PARM1(ctx));
+ data_args.fd = SYSCALL_PARM_1(ctx);
data_args.buf = buf;
data_args.start_nacs = bpf_ktime_get_ns();
data_args.data_id = generate_socket_data_id(id, data_args.fd,
SOCKET_OPTS_TYPE_WRITE);
@@ -687,12 +680,10 @@ int sys_send(struct pt_regs* ctx) {
if (tgid_should_trace(tgid) == false) {
return 0;
}
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
- char* buf;
- bpf_probe_read(&buf, sizeof(buf), &(PT_REGS_PARM2(ctx)));
+ char* buf = (void *)SYSCALL_PARM_2(ctx);
struct sock_data_args_t data_args = {};
- data_args.fd = _(PT_REGS_PARM1(ctx));
+ data_args.fd = SYSCALL_PARM_1(ctx);
data_args.buf = buf;
data_args.start_nacs = bpf_ktime_get_ns();
data_args.data_id = generate_socket_data_id(id, data_args.fd,
SOCKET_OPTS_TYPE_SEND);
@@ -720,13 +711,11 @@ int sys_writev(struct pt_regs* ctx) {
if (tgid_should_trace(tgid) == false) {
return 0;
}
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
- struct iovec *iovec;
- bpf_probe_read(&iovec, sizeof(iovec), &(PT_REGS_PARM2(ctx)));
+ struct iovec *iovec = (void *)SYSCALL_PARM_2(ctx);
struct sock_data_args_t data_args = {};
- data_args.fd = _(PT_REGS_PARM1(ctx));
- data_args.iovlen = _(PT_REGS_PARM3(ctx));
+ data_args.fd = SYSCALL_PARM_1(ctx);
+ data_args.iovlen = SYSCALL_PARM_3(ctx);
data_args.iovec = iovec;
data_args.start_nacs = bpf_ktime_get_ns();
data_args.data_id = generate_socket_data_id(id, data_args.fd,
SOCKET_OPTS_TYPE_WRITEV);
@@ -754,13 +743,11 @@ int sys_sendmsg(struct pt_regs* ctx) {
if (tgid_should_trace(tgid) == false) {
return 0;
}
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
- struct user_msghdr* msghdr;
- bpf_probe_read(&msghdr, sizeof(msghdr), &(PT_REGS_PARM2(ctx)));
+ struct user_msghdr* msghdr = (void *)SYSCALL_PARM_2(ctx);
if (msghdr == NULL) {
return 0;
}
- __u32 fd = _(PT_REGS_PARM1(ctx));
+ __u32 fd = SYSCALL_PARM_1(ctx);
struct sockaddr* addr = _(msghdr->msg_name);
if (addr != NULL) {
@@ -808,15 +795,13 @@ int sys_sendmmsg(struct pt_regs* ctx) {
if (tgid_should_trace(tgid) == false) {
return 0;
}
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
- struct mmsghdr* mmsghdr;
- bpf_probe_read(&mmsghdr, sizeof(mmsghdr), &(PT_REGS_PARM2(ctx)));
- __u32 vlen = _(PT_REGS_PARM3(ctx));
+ struct mmsghdr* mmsghdr = (void *)SYSCALL_PARM_2(ctx);
+ __u32 vlen = SYSCALL_PARM_3(ctx);
if (mmsghdr == NULL || vlen <= 0) {
return 0;
}
- __u32 fd = _(PT_REGS_PARM1(ctx));
+ __u32 fd = SYSCALL_PARM_1(ctx);
struct sockaddr* addr = _(mmsghdr->msg_hdr.msg_name);
if (addr != NULL) {
@@ -833,7 +818,7 @@ int sys_sendmmsg(struct pt_regs* ctx) {
data_args.iovec = msg_iov;
size_t msg_iovlen = _(mmsghdr->msg_hdr.msg_iovlen);
data_args.iovlen = msg_iovlen;
- data_args.msg_len = &mmsghdr->msg_hdr.msg_iovlen;
+ data_args.msg_len = (unsigned int*)(&mmsghdr->msg_hdr.msg_iovlen);
data_args.start_nacs = bpf_ktime_get_ns();
data_args.data_id = generate_socket_data_id(id, data_args.fd,
SOCKET_OPTS_TYPE_SENDMMSG);
bpf_map_update_elem(&socket_data_args, &id, &data_args, 0);
@@ -896,13 +881,12 @@ static __inline void process_sendfile(struct pt_regs*
ctx, __u64 id, struct send
SEC("kprobe/sendfile")
int sys_sendfile(struct pt_regs *ctx) {
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
__u64 id = bpf_get_current_pid_tgid();
struct sendfile_args_t args = {};
- args.out_fd = _(PT_REGS_PARM1(ctx));
- args.in_fd = _(PT_REGS_PARM2(ctx));
- args.count = _(PT_REGS_PARM4(ctx));
+ args.out_fd = SYSCALL_PARM_1(ctx);
+ args.in_fd = SYSCALL_PARM_2(ctx);
+ args.count = SYSCALL_PARM_4(ctx);
args.start_nacs = bpf_ktime_get_ns();
args.data_id = generate_socket_data_id(id, args.out_fd,
SOCKET_OPTS_TYPE_SENDFILE);
bpf_map_update_elem(&sendfile_args, &id, &args, 0);
@@ -928,12 +912,10 @@ int sys_read(struct pt_regs* ctx) {
if (tgid_should_trace(tgid) == false) {
return 0;
}
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
- char* buf;
- bpf_probe_read(&buf, sizeof(buf), &(PT_REGS_PARM2(ctx)));
+ char* buf = (void *)SYSCALL_PARM_2(ctx);
struct sock_data_args_t data_args = {};
- data_args.fd = _(PT_REGS_PARM1(ctx));
+ data_args.fd = SYSCALL_PARM_1(ctx);
data_args.buf = buf;
data_args.start_nacs = bpf_ktime_get_ns();
data_args.data_id = generate_socket_data_id(id, data_args.fd,
SOCKET_OPTS_TYPE_READ);
@@ -960,13 +942,11 @@ int sys_readv(struct pt_regs* ctx) {
if (tgid_should_trace(tgid) == false) {
return 0;
}
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
- struct iovec *iovec;
- bpf_probe_read(&iovec, sizeof(iovec), &(PT_REGS_PARM2(ctx)));
+ struct iovec *iovec = (void *)SYSCALL_PARM_2(ctx);
struct sock_data_args_t data_args = {};
- data_args.fd = _(PT_REGS_PARM1(ctx));
- data_args.iovlen = _(PT_REGS_PARM3(ctx));
+ data_args.fd = SYSCALL_PARM_1(ctx);
+ data_args.iovlen = SYSCALL_PARM_3(ctx);
data_args.iovec = iovec;
data_args.start_nacs = bpf_ktime_get_ns();
data_args.data_id = generate_socket_data_id(id, data_args.fd,
SOCKET_OPTS_TYPE_READV);
@@ -994,12 +974,10 @@ int sys_recv(struct pt_regs* ctx) {
if (tgid_should_trace(tgid) == false) {
return 0;
}
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
- char* buf;
- bpf_probe_read(&buf, sizeof(buf), &(PT_REGS_PARM2(ctx)));
+ char* buf = (void *)SYSCALL_PARM_2(ctx);
struct sock_data_args_t data_args = {};
- data_args.fd = _(PT_REGS_PARM1(ctx));
+ data_args.fd = SYSCALL_PARM_1(ctx);
data_args.buf = buf;
data_args.start_nacs = bpf_ktime_get_ns();
data_args.data_id = generate_socket_data_id(id, data_args.fd,
SOCKET_OPTS_TYPE_RECV);
@@ -1026,13 +1004,10 @@ int sys_recvfrom(struct pt_regs* ctx) {
if (tgid_should_trace(tgid) == false) {
return 0;
}
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
- char* buf;
- bpf_probe_read(&buf, sizeof(buf), &(PT_REGS_PARM2(ctx)));
+ char* buf = (void *)SYSCALL_PARM_2(ctx);
- struct sockaddr* sock;
- bpf_probe_read(&sock, sizeof(sock), &(PT_REGS_PARM5(ctx)));
- __u32 fd = _(PT_REGS_PARM1(ctx));
+ struct sockaddr* sock = (void *)SYSCALL_PARM_5(ctx);
+ __u32 fd = SYSCALL_PARM_1(ctx);
if (sock != NULL) {
struct connect_args_t connect_args = {};
connect_args.addr = sock;
@@ -1077,13 +1052,11 @@ int sys_recvmsg(struct pt_regs* ctx) {
if (tgid_should_trace(tgid) == false) {
return 0;
}
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
- struct user_msghdr* msghdr;
- bpf_probe_read(&msghdr, sizeof(msghdr), &(PT_REGS_PARM2(ctx)));
+ struct user_msghdr* msghdr = (void *)SYSCALL_PARM_2(ctx);
if (msghdr == NULL) {
return 0;
}
- __u32 fd = _(PT_REGS_PARM1(ctx));
+ __u32 fd = SYSCALL_PARM_1(ctx);
struct sockaddr* addr = _(msghdr->msg_name);
if (addr != NULL) {
@@ -1131,15 +1104,13 @@ int sys_recvmmsg(struct pt_regs* ctx) {
if (tgid_should_trace(tgid) == false) {
return 0;
}
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
- struct mmsghdr* mmsghdr;
- bpf_probe_read(&mmsghdr, sizeof(mmsghdr), &(PT_REGS_PARM2(ctx)));
- __u32 vlen = _(PT_REGS_PARM3(ctx));
+ struct mmsghdr* mmsghdr = (void *)SYSCALL_PARM_2(ctx);
+ __u32 vlen = SYSCALL_PARM_3(ctx);
if (mmsghdr == NULL || vlen <= 0) {
return 0;
}
- __u32 fd = _(PT_REGS_PARM1(ctx));
+ __u32 fd = SYSCALL_PARM_1(ctx);
struct sockaddr* addr = _(mmsghdr->msg_hdr.msg_name);
if (addr != NULL) {
@@ -1156,7 +1127,7 @@ int sys_recvmmsg(struct pt_regs* ctx) {
data_args.iovec = msg_iov;
size_t msg_iovlen = _(mmsghdr->msg_hdr.msg_iovlen);
data_args.iovlen = msg_iovlen;
- data_args.msg_len = &mmsghdr->msg_hdr.msg_iovlen;
+ data_args.msg_len = (unsigned int*)(&mmsghdr->msg_hdr.msg_iovlen);
data_args.start_nacs = bpf_ktime_get_ns();
data_args.data_id = generate_socket_data_id(id, data_args.fd,
SOCKET_OPTS_TYPE_RECVMMSG);
bpf_map_update_elem(&socket_data_args, &id, &data_args, 0);
@@ -1187,11 +1158,10 @@ int sys_recvmmsg_ret(struct pt_regs* ctx) {
SEC("kprobe/close")
int sys_close(struct pt_regs* ctx) {
- ctx = (struct pt_regs *)PT_REGS_PARM1(ctx);
__u64 id = bpf_get_current_pid_tgid();
struct sock_close_args_t close_args = {};
- close_args.fd = _(PT_REGS_PARM1(ctx));
+ close_args.fd = SYSCALL_PARM_1(ctx);
close_args.start_nacs = bpf_ktime_get_ns();
bpf_map_update_elem(&closing_args, &id, &close_args, 0);
return 0;
diff --git a/docker/Dockerfile.base b/docker/Dockerfile.base
index 759c17e..35a4fce 100644
--- a/docker/Dockerfile.base
+++ b/docker/Dockerfile.base
@@ -17,10 +17,10 @@
FROM golang:1.18
RUN apt update && \
- git clone --depth 1 --branch v0.8.0 https://github.com/libbpf/libbpf.git
&& \
+ git clone --depth 1 --branch v1.1.0 https://github.com/libbpf/libbpf.git
&& \
mkdir -p /usr/include/bpf && cp libbpf/src/*.h /usr/include/bpf && \
- apt install -y lsb-release wget software-properties-common libc6-dev-i386
&& \
- cp -rf /usr/include/asm-generic/* /usr/include/asm && \
+ apt install -y lsb-release wget software-properties-common "$([ $(uname
-m) = "x86_64" ] && echo "libc6-dev-i386" || echo "libc6-dev-armhf-cross")" && \
+ ([ $(uname -m) = "x86_64" ] && cp -rf /usr/include/asm-generic/*
/usr/include/asm || cp -rf /usr/include/$(uname -m)*/* /usr/include/) && \
wget https://apt.llvm.org/llvm.sh && \
chmod +x llvm.sh && \
./llvm.sh 13
diff --git a/docker/Dockerfile.build b/docker/Dockerfile.build
index 03e1be9..5255e42 100644
--- a/docker/Dockerfile.build
+++ b/docker/Dockerfile.build
@@ -26,7 +26,7 @@ COPY . .
ENV CGO_ENABLED=0
RUN VERSION=$VERSION make btfgen && make linux
-RUN mv /src/bin/skywalking-rover-${VERSION}-linux-amd64
/src/bin/skywalking-rover
+RUN mv /src/bin/skywalking-rover-${VERSION}-linux-* /src/bin/skywalking-rover
FROM alpine
diff --git a/pkg/profiling/continuous/checker/bpf/network/network.go
b/pkg/profiling/continuous/checker/bpf/network/network.go
index 26bdded..be6300c 100644
--- a/pkg/profiling/continuous/checker/bpf/network/network.go
+++ b/pkg/profiling/continuous/checker/bpf/network/network.go
@@ -33,7 +33,7 @@ import (
// $BPF_CLANG and $BPF_CFLAGS are set by the Makefile.
// nolint
-//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -no-global-types
-target bpfel -cc $BPF_CLANG -cflags $BPF_CFLAGS bpf
$REPO_ROOT/bpf/profiling/continuous/network.c -- -I$REPO_ROOT/bpf/include
-D__TARGET_ARCH_x86
+//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -no-global-types
-target $TARGET -cc $BPF_CLANG -cflags $BPF_CFLAGS bpf
$REPO_ROOT/bpf/profiling/continuous/network.c -- -I$REPO_ROOT/bpf/include
var log = logger.GetLogger("profiling", "continuous", "checker", "network",
"bpf")
diff --git a/pkg/profiling/task/network/analyze/layer7/protocols/base/buffer.go
b/pkg/profiling/task/network/analyze/layer7/protocols/base/buffer.go
index ec374fc..e6c19b9 100644
--- a/pkg/profiling/task/network/analyze/layer7/protocols/base/buffer.go
+++ b/pkg/profiling/task/network/analyze/layer7/protocols/base/buffer.go
@@ -129,7 +129,7 @@ func (r *Buffer) Slice(validated bool, start, end
*BufferPosition) *Buffer {
}
func (r *Buffer) Len() int {
- if r.head == nil {
+ if r == nil || r.head == nil {
return 0
}
var result int
diff --git a/pkg/profiling/task/network/bpf/bpf.go
b/pkg/profiling/task/network/bpf/bpf.go
index d4dc7fa..083935c 100644
--- a/pkg/profiling/task/network/bpf/bpf.go
+++ b/pkg/profiling/task/network/bpf/bpf.go
@@ -25,7 +25,7 @@ import (
// $BPF_CLANG and $BPF_CFLAGS are set by the Makefile.
// nolint
-//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -no-global-types
-target bpfel -cc $BPF_CLANG -cflags $BPF_CFLAGS bpf
$REPO_ROOT/bpf/profiling/network/netmonitor.c -- -I$REPO_ROOT/bpf/include
-D__TARGET_ARCH_x86
+//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -no-global-types
-target $TARGET -cc $BPF_CLANG -cflags $BPF_CFLAGS bpf
$REPO_ROOT/bpf/profiling/network/netmonitor.c -- -I$REPO_ROOT/bpf/include
type Loader struct {
*btf.Linker
diff --git a/pkg/profiling/task/offcpu/runner.go
b/pkg/profiling/task/offcpu/runner.go
index 9c8c7e9..83d25ab 100644
--- a/pkg/profiling/task/offcpu/runner.go
+++ b/pkg/profiling/task/offcpu/runner.go
@@ -41,7 +41,7 @@ import (
// $BPF_CLANG and $BPF_CFLAGS are set by the Makefile.
// nolint
-//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -no-global-types
-target bpfel -cc $BPF_CLANG -cflags $BPF_CFLAGS bpf
$REPO_ROOT/bpf/profiling/offcpu.c -- -I$REPO_ROOT/bpf/include
-D__TARGET_ARCH_x86
+//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -no-global-types
-target $TARGET -cc $BPF_CLANG -cflags $BPF_CFLAGS bpf
$REPO_ROOT/bpf/profiling/offcpu.c -- -I$REPO_ROOT/bpf/include
var log = logger.GetLogger("profiling", "task", "offcpu")
var defaultKernelSymbol = "finish_task_switch"
diff --git a/pkg/tools/btf/linker.go b/pkg/tools/btf/linker.go
index d08242a..66ef34b 100644
--- a/pkg/tools/btf/linker.go
+++ b/pkg/tools/btf/linker.go
@@ -24,8 +24,10 @@ import (
"fmt"
"io"
"os"
+ "runtime"
"sync"
+ "golang.org/x/arch/arm64/arm64asm"
"golang.org/x/arch/x86/x86asm"
"github.com/apache/skywalking-rover/pkg/tools/elf"
@@ -299,16 +301,33 @@ func (u *UProbeExeFile) addGoExitLink0(symbol string, p
*ebpf.Program, elfFile *
// https://github.com/iovisor/bcc/issues/1320#issuecomment-407927542
var addresses []uint64
for i := 0; i < int(targetSymbol.Size); {
- inst, err := x86asm.Decode(buffer[i:], 64)
- if err != nil {
- return nil, fmt.Errorf("error decode the function data:
%v", err)
- }
+ var instLen int
+ if runtime.GOARCH == "arm64" {
+ inst, err := arm64asm.Decode(buffer[i:])
+ if err != nil {
+ i += 4
+ continue
+ }
+
+ if inst.Op == arm64asm.RET {
+ addresses = append(addresses, uint64(i))
+ }
+
+ instLen = 4
+ } else {
+ inst, err := x86asm.Decode(buffer[i:], 64)
+ if err != nil {
+ return nil, fmt.Errorf("error decode the
function data: %v", err)
+ }
+
+ if inst.Op == x86asm.RET {
+ addresses = append(addresses, uint64(i))
+ }
- if inst.Op == x86asm.RET {
- addresses = append(addresses, uint64(i))
+ instLen = inst.Len
}
- i += inst.Len
+ i += instLen
}
if len(addresses) == 0 {
diff --git a/pkg/tools/elf/abi.go b/pkg/tools/elf/abi.go
index de34660..c8648c0 100644
--- a/pkg/tools/elf/abi.go
+++ b/pkg/tools/elf/abi.go
@@ -125,11 +125,13 @@ type GolangStackLocator struct {
curStackOffset uint64
}
-func (g *GolangStackLocator) GetLocation(_ TypeClass, _, alignmentSize uint64,
_ int, _ bool) (*ArgLocation, error) {
+func (g *GolangStackLocator) GetLocation(_ TypeClass, typeSize, alignmentSize
uint64, _ int, _ bool) (*ArgLocation, error) {
g.curStackOffset = snapUpToMultiple(g.curStackOffset, alignmentSize)
result := &ArgLocation{}
result.Type = ArgLocationTypeStack
result.Offset = g.curStackOffset
+
+ g.curStackOffset += typeSize
return result, nil
}
@@ -142,5 +144,5 @@ func (u *UnknownLocator) GetLocation(typeClass TypeClass,
typeSize, alignmentSiz
}
func snapUpToMultiple(curSize, alignmentSize uint64) uint64 {
- return (curSize + (alignmentSize-1)/alignmentSize) * alignmentSize
+ return ((curSize + (alignmentSize - 1)) / alignmentSize) * alignmentSize
}
diff --git a/scripts/build/base.mk b/scripts/build/base.mk
index ac87445..e302bdb 100644
--- a/scripts/build/base.mk
+++ b/scripts/build/base.mk
@@ -37,17 +37,30 @@ CONTAINER_COMMAND_TAG ?= v$(VERSION)
CONTAINER_COMMAND_CLANG ?= clang
CONTAINER_COMMAND_STRIP ?= llvm-strip
CONTAINER_COMMAND_CFLAGS := -O2 -g -Wall -Werror $(CFLAGS)
-CONTAINER_COMMAND_ENGINE ?= docker
+CONTAINER_PLATFORMS ?= --platform linux/amd64,linux/arm64
+
+SYS_ARCH := $(shell uname -m)
.PHONY: clean
clean:
-rm -rf coverage.txt
build-base-container:
- ${CONTAINER_COMMAND_ENGINE} build -t
${CONTAINER_COMMAND_IMAGE}:${CONTAINER_COMMAND_TAG} . -f docker/Dockerfile.base
+ docker build -t ${CONTAINER_COMMAND_IMAGE}:${CONTAINER_COMMAND_TAG} .
-f docker/Dockerfile.base
+
+build-base-container-with-multi-args-cleanup:
+ docker stop registry && docker rm registry || true
+ docker buildx rm skywalking_rover || true
+
+build-base-container-with-multi-args:
build-base-container-with-multi-args-cleanup
+ # needs to push the base image into local registry when building
multiple platforms image
+ # following https://github.com/docker/buildx/issues/1453
+ docker run -d --name registry --network=host registry:2
+ docker buildx create --use --driver-opt network=host --name
skywalking_rover || true
+ docker buildx build --push ${CONTAINER_PLATFORMS} -t
localhost:5000/skywalking-rover-base:${CONTAINER_COMMAND_TAG} . -f
docker/Dockerfile.base
container-command: build-base-container
- ${CONTAINER_COMMAND_ENGINE} run --rm \
+ docker run --rm \
-v "${REPODIR}":/skywalking-rover -w /skywalking-rover --env
MAKEFLAGS \
--env CFLAGS="-fdebug-prefix-map=/skywalking-rover=." \
--env HOME="/skywalking-rover" \
diff --git a/scripts/build/btf.mk b/scripts/build/btf.mk
index b6e33cc..949d125 100644
--- a/scripts/build/btf.mk
+++ b/scripts/build/btf.mk
@@ -16,9 +16,15 @@
# under the License.
#
+ifeq ($(SYS_ARCH),x86_64)
+ BTF_ARCH := x86_64
+else
+ BTF_ARCH := arm64
+endif
+
.PHONY: btfgen
btfgen: generate
- bash ${REPODIR}/scripts/build/bash/btfgen.sh /tmp x86_64 ${REPODIR}
${REPODIR}/pkg/tools/btf/files
+ bash ${REPODIR}/scripts/build/bash/btfgen.sh /tmp ${BTF_ARCH}
${REPODIR} ${REPODIR}/pkg/tools/btf/files
# Usually works for generate BTF file on Mac OS or windows
.PHONY: container-btfgen
diff --git a/scripts/build/build.mk b/scripts/build/build.mk
index edad491..465117b 100644
--- a/scripts/build/build.mk
+++ b/scripts/build/build.mk
@@ -23,7 +23,11 @@ GO_BUILD_FLAGS = -v
GO_BUILD_LDFLAGS = -X main.version=$(VERSION)
PLATFORMS := linux
-ARCH = amd64
+ifeq ($(SYS_ARCH),x86_64)
+ ARCH := amd64
+else
+ ARCH := arm64
+endif
os = $(word 1, $@)
deps:
@@ -35,4 +39,4 @@ $(PLATFORMS): deps
GOOS=$(os) GOARCH=$(ARCH) $(GO_BUILD) $(GO_BUILD_FLAGS) -ldflags
"$(GO_BUILD_LDFLAGS)" -o $(OUT_DIR)/$(BINARY)-$(VERSION)-$(os)-$(ARCH) ./cmd
.PHONY: build
-build: linux
\ No newline at end of file
+build: linux
diff --git a/scripts/build/docker.mk b/scripts/build/docker.mk
index 04136bb..be4fb18 100644
--- a/scripts/build/docker.mk
+++ b/scripts/build/docker.mk
@@ -16,11 +16,22 @@
# under the License.
#
-.PHONY: docker
+docker: PLATFORMS =
+docker: LOAD_OR_PUSH = --load
docker: build-base-container
- docker build --build-arg VERSION=$(VERSION) --build-arg
BASE_IMAGE=${CONTAINER_COMMAND_IMAGE}:${CONTAINER_COMMAND_TAG} \
- -t $(HUB)/skywalking-rover:$(VERSION) --no-cache . -f
docker/Dockerfile.build
+docker: BASE_IMAGE_NAME = ${CONTAINER_COMMAND_IMAGE}
+docker.push: PLATFORMS = ${CONTAINER_PLATFORMS}
+docker.push: LOAD_OR_PUSH = --push
+docker.push: build-base-container-with-multi-args
+docker.push: BASE_IMAGE_NAME = localhost:5000/skywalking-rover-base
+
+docker docker.push:
+ $(DOCKER_RULE)
-.PHONY: docker.push
-docker.push:
- docker push $(HUB)/skywalking-rover:$(VERSION)
\ No newline at end of file
+define DOCKER_RULE
+ docker buildx build ${PLATFORMS} ${LOAD_OR_PUSH} \
+ --build-arg VERSION=$(VERSION) \
+ --build-arg
BASE_IMAGE=${BASE_IMAGE_NAME}:${CONTAINER_COMMAND_TAG} \
+ -t $(HUB)/skywalking-rover:$(VERSION) --no-cache . -f
docker/Dockerfile.build
+ @$(MAKE) build-base-container-with-multi-args-cleanup
+endef
diff --git a/scripts/build/generate.mk b/scripts/build/generate.mk
index 1a46c4a..4ce209c 100644
--- a/scripts/build/generate.mk
+++ b/scripts/build/generate.mk
@@ -21,7 +21,7 @@ generate: export BPF_CLANG := $(CONTAINER_COMMAND_CLANG)
generate: export BPF_CFLAGS := $(CONTAINER_COMMAND_CFLAGS)
generate: export REPO_ROOT := $(REPODIR)
generate:
- cd ./ && go generate ./...
+ cd ./ && TARGET=$(if $(findstring x86_64,$(shell uname
-m)),amd64,arm64) go generate ./...
# Usually works for generate ebpf ELF file on Mac OS or windows
.PHONY: container-generate