From de48769ded5c76b96354304461ed18c2e2b0e4ad Mon Sep 17 00:00:00 2001 From: nolanmar Date: Mon, 6 Jul 2020 14:43:47 -0700 Subject: [PATCH 1/5] Update curl version used to build agent. PiperOrigin-RevId: 319859034 --- Dockerfile | 2 +- Dockerfile.alpine | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index baf2b6b25..589721ceb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -56,7 +56,7 @@ RUN mkdir /tmp/openssl && cd /tmp/openssl && \ cd ~ && rm -rf /tmp/openssl # curl -RUN git clone --depth=1 -b curl-7_66_0 https://github.com/curl/curl.git /tmp/curl && \ +RUN git clone --depth=1 -b curl-7_69_1 https://github.com/curl/curl.git /tmp/curl && \ cd /tmp/curl && \ ./buildconf && \ ./configure --disable-ldap --disable-shared --without-libssh2 \ diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 80bcb78de..19237cd2f 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -54,7 +54,7 @@ RUN mkdir /tmp/openssl && cd /tmp/openssl && \ cd ~ && rm -rf /tmp/openssl # curl -RUN git clone --depth=1 -b curl-7_66_0 https://github.com/curl/curl.git /tmp/curl && \ +RUN git clone --depth=1 -b curl-7_69_1 https://github.com/curl/curl.git /tmp/curl && \ cd /tmp/curl && \ ./buildconf && \ ./configure --disable-ldap --disable-shared --without-libssh2 \ From d092dc76793766cbd835e7c38c078f27531fec9e Mon Sep 17 00:00:00 2001 From: cloud-profiler-team Date: Wed, 12 Aug 2020 19:04:08 -0700 Subject: [PATCH 2/5] Internal change PiperOrigin-RevId: 326361710 --- src/cloud_profiler_java_agent.lds | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cloud_profiler_java_agent.lds b/src/cloud_profiler_java_agent.lds index cb432ed37..b7dcacebd 100644 --- a/src/cloud_profiler_java_agent.lds +++ b/src/cloud_profiler_java_agent.lds @@ -1,5 +1,6 @@ VERS_1.0 { global: + google_find_phdr; Agent_OnLoad; Agent_OnUnload; Java_org_apache_beam_runners_dataflow_worker_profiler_Profiler_disable; From ef0ea3fe6187f14087a203d3907c1002e098e72e Mon Sep 17 00:00:00 2001 From: nolanmar Date: Wed, 14 Oct 2020 14:15:46 -0700 Subject: [PATCH 3/5] Run formatter on agent code. PiperOrigin-RevId: 337169814 --- src/clock.h | 6 ++---- src/globals.h | 14 +++++++------- src/http.cc | 2 +- src/profiler.cc | 3 ++- src/proto.cc | 1 + src/threads.h | 1 + src/uploader_gcs.cc | 1 - 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/clock.h b/src/clock.h index 5b4b9a267..2937d5468 100644 --- a/src/clock.h +++ b/src/clock.h @@ -24,8 +24,8 @@ namespace cloud { namespace profiler { using google::javaprofiler::Clock; -using google::javaprofiler::kNanosPerSecond; using google::javaprofiler::kNanosPerMilli; +using google::javaprofiler::kNanosPerSecond; inline struct timespec TimeAdd(const struct timespec t1, const struct timespec t2) { @@ -44,9 +44,7 @@ inline int64_t TimeSpecToNanos(const struct timespec &ts) { return google::javaprofiler::TimeSpecToNanos(ts); } -inline Clock *DefaultClock() { - return google::javaprofiler::DefaultClock(); -} +inline Clock *DefaultClock() { return google::javaprofiler::DefaultClock(); } } // namespace profiler } // namespace cloud diff --git a/src/globals.h b/src/globals.h index ceada6811..3c63458c4 100644 --- a/src/globals.h +++ b/src/globals.h @@ -55,17 +55,17 @@ namespace profiler { // easier to just re-use the constants this way to keep the code easy to read. // // Remove this when porting is done. +using google::javaprofiler::kDeopt; +using google::javaprofiler::kGcActive; using google::javaprofiler::kNativeStackTrace; using google::javaprofiler::kNoClassLoad; -using google::javaprofiler::kGcActive; -using google::javaprofiler::kUnknownNotJava; +using google::javaprofiler::kNotWalkableFrameJava; using google::javaprofiler::kNotWalkableFrameNotJava; +using google::javaprofiler::kSafepoint; +using google::javaprofiler::kThreadExit; using google::javaprofiler::kUnknownJava; -using google::javaprofiler::kNotWalkableFrameJava; +using google::javaprofiler::kUnknownNotJava; using google::javaprofiler::kUnknownState; -using google::javaprofiler::kThreadExit; -using google::javaprofiler::kDeopt; -using google::javaprofiler::kSafepoint; using google::javaprofiler::kCallTraceErrorLineNum; using google::javaprofiler::kMaxFramesToCapture; @@ -76,7 +76,7 @@ using google::javaprofiler::JVMPI_CallFrame; using google::javaprofiler::JVMPI_CallTrace; // Gets us around -Wunused-parameter -#define IMPLICITLY_USE(x) (void) x; +#define IMPLICITLY_USE(x) (void)x; #define AGENTEXPORT __attribute__((visibility("default"))) JNIEXPORT diff --git a/src/http.cc b/src/http.cc index 0c4adc196..60bc94062 100644 --- a/src/http.cc +++ b/src/http.cc @@ -91,7 +91,7 @@ bool HTTPRequest::DoRequest(const std::string& url) { size_t HTTPRequest::ResponseCallback(void* contents, size_t size, size_t nmemb, std::string* resp) { size_t real_size = size * nmemb; - resp->append(static_cast(contents), real_size); + resp->append(static_cast(contents), real_size); return real_size; } diff --git a/src/profiler.cc b/src/profiler.cc index 4031936af..37237e85c 100644 --- a/src/profiler.cc +++ b/src/profiler.cc @@ -135,7 +135,8 @@ void Profiler::Handle(int signum, siginfo_t *info, void *context) { // counter in such case to provide at least some clue into where the time is // being spent. The alternative would be to mark such samples as erroneous // but it appears even having just the shared object name is more useful. - uint64_t pc = static_cast(context)->uc_mcontext.gregs[REG_RIP]; + uint64_t pc = + static_cast(context)->uc_mcontext.gregs[REG_RIP]; trace.frames[0] = JVMPI_CallFrame{kNativeFrameLineNum, reinterpret_cast(pc)}; ++trace.num_frames; diff --git a/src/proto.cc b/src/proto.cc index 1c04170ac..6dcd905c9 100644 --- a/src/proto.cc +++ b/src/proto.cc @@ -17,6 +17,7 @@ #include #include #include + #include #include diff --git a/src/threads.h b/src/threads.h index ad41f0ead..6a44d0aa6 100644 --- a/src/threads.h +++ b/src/threads.h @@ -18,6 +18,7 @@ #define CLOUD_PROFILER_AGENT_JAVA_THREADS_H_ #include + #include // NOLINT(build/c++11) #include diff --git a/src/uploader_gcs.cc b/src/uploader_gcs.cc index b2a2f3da0..a28369fe0 100644 --- a/src/uploader_gcs.cc +++ b/src/uploader_gcs.cc @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. - #include "src/uploader_gcs.h" #include From f6873797ead4779b5cc4609f70061f347e393855 Mon Sep 17 00:00:00 2001 From: kchadalavada Date: Mon, 19 Oct 2020 22:38:39 -0700 Subject: [PATCH 4/5] Update glog to v0.4.0. PiperOrigin-RevId: 338001184 --- Dockerfile | 4 ++-- Dockerfile.alpine | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 589721ceb..50c6af32a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -75,8 +75,8 @@ RUN git clone --depth=1 -b v2.1.2 https://github.com/gflags/gflags.git /tmp/gfla # google-glog RUN mkdir /tmp/glog && cd /tmp/glog && \ - curl -sL https://github.com/google/glog/archive/v0.3.5.tar.gz | \ - tar xzv --strip=1 && ./configure --with-pic && \ + curl -sL https://github.com/google/glog/archive/v0.4.0.tar.gz | \ + tar xzv --strip=1 && ./autogen.sh && ./configure --with-pic && \ make -j && make install && \ cd ~ && rm -rf /tmp/glog diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 19237cd2f..b4922a962 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -73,8 +73,9 @@ RUN git clone --depth=1 -b v2.1.2 https://github.com/gflags/gflags.git /tmp/gfla # google-glog RUN mkdir /tmp/glog && cd /tmp/glog && \ - curl -sL https://github.com/google/glog/archive/v0.3.5.tar.gz | \ - tar xzv --strip=1 && LDFLAGS="-lexecinfo" ./configure --with-pic --enable-static && \ + curl -sL https://github.com/google/glog/archive/v0.4.0.tar.gz | \ + tar xzv --strip=1 && ./autogen.sh && \ + LDFLAGS="-lexecinfo" ./configure --with-pic --enable-static && \ make -j && make install && \ cd ~ && rm -rf /tmp/glog From b13131e5eeb48bebc7fcbf114bfb6e677d6254ec Mon Sep 17 00:00:00 2001 From: kchadalavada Date: Wed, 21 Oct 2020 10:28:38 -0700 Subject: [PATCH 5/5] Support building on ARM64. For testing only, no support. PiperOrigin-RevId: 338290512 --- Makefile | 16 ++++++++++++++-- README.md | 15 +++++++++++++-- build.sh | 46 ++++++++++++++++++++++++++++++++++++++++------ src/profiler.cc | 4 ++++ 4 files changed, 71 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 159a9be80..8e3c3a222 100644 --- a/Makefile +++ b/Makefile @@ -14,9 +14,11 @@ CC = g++ +# Determine the machine type. +machine_type := $(shell uname -m) + # -fpermissive used to bypass <:: errors from gcc 4.7 CFLAGS = \ - -m64 \ -std=c++11 \ -fpermissive \ -fPIC \ @@ -31,13 +33,23 @@ CFLAGS = \ -D_GNU_SOURCE \ -DENABLE_HEAP_SAMPLING +ifeq ($(machine_type),$(filter $(machine_type),aarch64 arm64)) + # Building on an ARM64 machine. + CFLAGS += \ + -march=native \ + -mtune=native \ + -mcpu=native + JAVA_PATH ?= /usr/lib/jvm/java-11-openjdk-arm64 +else + CFLAGS += -m64 + JAVA_PATH ?= /usr/lib/jvm/java-11-openjdk-amd64 +endif ifneq ($(AGENT_VERSION),) CFLAGS += -DCLOUD_PROFILER_AGENT_VERSION=\"$(AGENT_VERSION)\" endif SRC_ROOT_PATH=. -JAVA_PATH ?= /usr/lib/jvm/java-11-openjdk-amd64 PROTOC ?= /usr/local/bin/protoc PROTOC_GEN_GRPC ?= /usr/local/bin/grpc_cpp_plugin diff --git a/README.md b/README.md index 5e93a5fdf..e9169732a 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ commands below. $ ./build.sh ``` -## To build for Alpine. +## To build for Alpine **Only Alpine versions 3.11 and later are currently supported.** @@ -39,5 +39,16 @@ the flag `-cprof_cpu_use_per_thread_timers` is ignored on this platform. ```shell $ git clone https://github.com/GoogleCloudPlatform/cloud-profiler-java.git $ cd cloud-profiler-java -$ ./build.sh -a +$ ./build.sh -m alpine +``` + +## To build for ARM64 + +**Support for ARM64 is provided for testing purposes only.** The following +commands must be run on an ARM64 machine. Cross compilation is not supported. + +```shell +$ git clone https://github.com/GoogleCloudPlatform/cloud-profiler-java.git +$ cd cloud-profiler-java +$ ./build.sh -m arm64 ``` diff --git a/build.sh b/build.sh index 0fd47e123..ec5ccbd9c 100755 --- a/build.sh +++ b/build.sh @@ -21,20 +21,52 @@ set -o nounset # # Command line arguments: [-d] # -d: specify the temporary directory for the build. +# -m: use 'amd64' to build for amd64, 'alpine' for Alpine Linux, +# 'arm64' for ARM64. Omitting -m builds for amd64. # -v: the version for this build of the agent. +ARM64_BUILD="0" ALPINE_BUILD="0" DOCKERFILE="Dockerfile" FILE_SUFFIX="" -while getopts ":ad:v:" opt; do +MACHINE_TYPE=$(uname -m) +while getopts ":d:m:v:" opt; do case $opt in - a) - ALPINE_BUILD="1" - FILE_SUFFIX="_alpine" - ;; d) BUILD_TEMP_DIR=$OPTARG ;; + m) + TARGET=$OPTARG + if [[ "${TARGET}" == "arm64" ]]; then + if [[ "${MACHINE_TYPE}" != "aarch64" ]] || [[ "${MACHINE_TYPE}" != "arm64" ]]; then + echo "-m arm64 is supported only when running on an ARM64 system." + exit; + fi + ARM64_BUILD="1" + FILE_SUFFIX="_arm64" + ALPINE_BUILD="0" + echo "Building for ARM64 is provided only for testing." + elif [[ "${TARGET}" == "alpine" ]]; then + if [[ "${MACHINE_TYPE}" != "x86_64" ]]; then + echo "-m alpine is supported only when running on an x86_64 system." + exit; + fi + ALPINE_BUILD="1" + FILE_SUFFIX="_alpine" + ARM64_BUILD="0" + elif [[ "${TARGET}" == "amd64" ]]; then + if [[ "${MACHINE_TYPE}" != "x86_64" ]]; then + echo "-m amd64 is supported only when running on an x86_64 system." + exit; + fi + ARM64_BUILD="0" + ALPINE_BUILD="0" + FILE_SUFFIX="" + else + echo "-m must be either amd64, arm64 or alpine." + exit; + fi + ;; v) VERSION=$OPTARG ;; @@ -75,10 +107,12 @@ mkdir -p "${BUILD_TEMP_DIR}" if [[ "${ALPINE_BUILD}" = "1" ]]; then PrintMessage "Building the builder Alpine Docker container..." DOCKERFILE="Dockerfile.alpine" +elif [[ "${ARM64_BUILD}" = "1" ]]; then + PrintMessage "Building the builder ARM64 Docker container..." else PrintMessage "Building the builder Docker container..." fi - docker build -f "${DOCKERFILE}" -t cprof-agent-builder . >> "${LOG_FILE}" 2>&1 +docker build -f "${DOCKERFILE}" -t cprof-agent-builder . >> "${LOG_FILE}" 2>&1 PrintMessage "Packaging the agent code..." mkdir -p "${BUILD_TEMP_DIR}"/build diff --git a/src/profiler.cc b/src/profiler.cc index 37237e85c..2cc1bbf9f 100644 --- a/src/profiler.cc +++ b/src/profiler.cc @@ -135,8 +135,12 @@ void Profiler::Handle(int signum, siginfo_t *info, void *context) { // counter in such case to provide at least some clue into where the time is // being spent. The alternative would be to mark such samples as erroneous // but it appears even having just the shared object name is more useful. +#ifdef __aarch64__ + uint64_t pc = static_cast(context)->uc_mcontext.pc; +#else uint64_t pc = static_cast(context)->uc_mcontext.gregs[REG_RIP]; +#endif trace.frames[0] = JVMPI_CallFrame{kNativeFrameLineNum, reinterpret_cast(pc)}; ++trace.num_frames;