Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
ac558e0
Internal Change
psx95 Mar 6, 2023
ec99768
Internal Code Change
Mar 9, 2023
7661ece
Add missing proto build steps to Makefile builds
Mar 20, 2023
d351ca4
Internal Code Change
Mar 30, 2023
936195e
Internal Code Change
Mar 30, 2023
36ff8bf
Internal Code Change
Mar 31, 2023
92f1c25
Prevent segfaults due to race conditions when Java Heap sampler is en…
Apr 3, 2023
6f863ed
Prevent other segfaults due to race conditions when Java Heap sampler…
Apr 6, 2023
e39cf71
Prevent memory leak due to race conditions when Java Heap sampler is …
Apr 11, 2023
ce2c8ba
Internal testing logs
psx95 May 19, 2023
f337ee2
Internal testing logs
psx95 May 22, 2023
eb3a79b
Split out ThreadProfile code to a separate target in order to add uni…
Jul 15, 2023
c61ed70
Internal Code Change
Aug 10, 2023
e4e93e8
Remove uses of the deprecated DISALLOW_IMPLICIT_CONSTRUCTORS in favor…
Aug 12, 2023
db5c7f7
Internal Code Change
Aug 17, 2023
2e6da4d
Change `T const&&` to `T`.
Oct 11, 2023
c10f720
Fix SIGSEGV in `HeapMonitor` during shutdown
Oct 24, 2023
1088b13
Update roots.pem to align with the current public set
Oct 26, 2023
6ec4263
Fix potential crash in shutdown due to null jvmti_ pointer.
Oct 31, 2023
42ca11c
Update profile.proto to match pprof's original.
aalexand Nov 1, 2023
59b51b3
Fix ClangTidy warnings and format code.
Nov 8, 2023
7398414
Make HeapMonitor::Enable()'s use_jvm_trace parameter default to false.
Dec 7, 2023
814af54
Allow users to configure the max number of garbage traces via a param…
Dec 8, 2023
f349ca4
Fix overflow in heap_sampler when a single object's size is greater t…
Dec 14, 2023
4606afa
Internal Code Change
Dec 27, 2023
f684356
Unconditionally define `DISALLOW_COPY_AND_ASSIGN`
Jan 2, 2024
0d1fdf5
Automated Code Change
Jan 16, 2024
5cac52e
Sync changes to profile.proto.
Jan 17, 2024
9037e4d
chore: update gRPC to v1.36.4
psx95 Feb 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 53 additions & 15 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,22 @@ FROM ubuntu:xenial
#
# Dependencies
#
# Install JDK 11 as sampling heap profiler depends on the new JVMTI APIs
# Install Kitware apt repository. This repository contains newer version of
# CMake. CMake > 3.13 is required to use "module" mode for gRPC dependencies.
# See https://github.com/grpc/grpc/blob/master/BUILDING.md#install-after-build.
# Kitware installs CMake v3.20.5

# Install JDK 11 as sampling heap profiler depends on the new JVMTI APIs.
RUN apt-get update && apt-get install -y software-properties-common
RUN add-apt-repository -y ppa:openjdk-r/ppa
RUN apt-get update
RUN apt-get update && apt-get install -y software-properties-common apt-transport-https ca-certificates gnupg wget && \
add-apt-repository -y ppa:openjdk-r/ppa && \
test -f /usr/share/doc/kitware-archive-keyring/copyright || \
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null \
| gpg --dearmor - \
| tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null && \
echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ xenial main' \
| tee /etc/apt/sources.list.d/kitware.list >/dev/null && \
apt-get update && \
apt-get install kitware-archive-keyring

# Installing openjdk-11-jdk-headless can be very slow due to repo download
# speed.
Expand All @@ -41,6 +52,7 @@ RUN apt-get update && apt-get -y -q install \
libtool \
make \
openjdk-11-jdk-headless \
pkg-config \
unzip \
zlib1g-dev

Expand Down Expand Up @@ -81,21 +93,47 @@ RUN mkdir /tmp/glog && cd /tmp/glog && \
make -j && make install && \
cd ~ && rm -rf /tmp/glog

# gRPC & protobuf
# gRPC & protobuf - build using CMake
# Use the protobuf version from gRPC for everything to avoid conflicting
# versions to be linked in. Disable OpenSSL embedding: when it's on, the build
# process of gRPC puts the OpenSSL static object files into the gRPC archive
# which causes link errors later when the agent is linked with the static
# OpenSSL library itself.
# Limit the number of threads used by make, as unlimited threads causes
# memory exhausted error on the Kokoro VM.
RUN git clone --depth=1 --recursive -b v1.28.1 https://github.com/grpc/grpc.git /tmp/grpc && \
cd /tmp/grpc && \
cd third_party/protobuf && \
./autogen.sh && \
./configure --with-pic CXXFLAGS="$(pkg-config --cflags protobuf)" LIBS="$(pkg-config --libs protobuf)" LDFLAGS="-Wl,--no-as-needed" && \
make -j4 && make install && ldconfig && \
cd ../.. && \
CPPFLAGS="-I /usr/local/ssl/include" LDFLAGS="-L /usr/local/ssl/lib/ -Wl,--no-as-needed" make -j4 CONFIG=opt EMBED_OPENSSL=false V=1 HAS_SYSTEM_OPENSSL_NPN=0 && \
CPPFLAGS="-I /usr/local/ssl/include" LDFLAGS="-L /usr/local/ssl/lib/ -Wl,--no-as-needed" make CONFIG=opt EMBED_OPENSSL=false V=1 HAS_SYSTEM_OPENSSL_NPN=0 install && \
rm -rf /tmp/grpc
# -DCMAKE_CXX_STANDARD=11 is necessary since it is the minimum version supported
# by gRPC dependencies. Xenial sets default version to c++98.
#
# See https://github.com/grpc/grpc/blob/v1.36.4/test/distrib/cpp/run_distrib_test_cmake_pkgconfig.sh
RUN git clone --depth=1 --recursive -b v1.36.4 https://github.com/grpc/grpc.git /tmp/grpc && \
cd /tmp/grpc/ && \
# Install protobuf
mkdir -p third_party/protobuf/cmake/build && \
(cd third_party/protobuf/cmake/build && \
cmake -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_CXX_STANDARD=11 -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE -DCMAKE_BUILD_TYPE=Release .. && \
make -j4 install) && \
# Install finish - protobuf
# Install gRPC
mkdir -p cmake/build && \
(cd cmake/build && \
cmake \
-DOPENSSL_ROOT_DIR=/usr/local/ssl \
-DOPENSSL_INCLUDE_DIR=/usr/local/ssl/include \
-DOPENSSL_CRYPTO_LIB=/usr/local/ssl/lib \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=11 \
-DCMAKE_INSTALL_PREFIX=/usr/local/grpc \
-DgRPC_INSTALL=ON \
-DgRPC_BUILD_TESTS=OFF \
-DgRPC_ABSL_PROVIDER=module \
-DgRPC_CARES_PROVIDER=module \
-DgRPC_RE2_PROVIDER=module \
-DgRPC_ZLIB_PROVIDER=module \
-DgRPC_PROTOBUF_PROVIDER=package \
-DgRPC_SSL_PROVIDER=package \
../.. && \
make -j4 install) && \
cd ~ && rm -rf /tmp/grpc

ENV PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/usr/local/ssl/lib/pkgconfig:/usr/local/grpc/lib/pkgconfig:/usr/local/lib64/pkgconfig"
ENV PATH="${PATH}:/usr/local/grpc/bin"
45 changes: 33 additions & 12 deletions Dockerfile.alpine
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ RUN apk --no-cache add \
# openssl
# This openssl (compiled with -fPIC) is used to statically link into the agent
# shared library.
ENV PKG_CONFIG_PATH=/usr/local/ssl/lib/pkgconfig
ENV JAVA_PATH=/usr/lib/jvm/java-11-openjdk/
RUN mkdir /tmp/openssl && cd /tmp/openssl && \
curl -sL https://github.com/openssl/openssl/archive/OpenSSL_1_1_1t.tar.gz | \
Expand Down Expand Up @@ -80,21 +79,43 @@ RUN mkdir /tmp/glog && cd /tmp/glog && \
make -j && make install && \
cd ~ && rm -rf /tmp/glog

# gRPC & protobuf
# gRPC & protobuf - build using CMake
# Use the protobuf version from gRPC for everything to avoid conflicting
# versions to be linked in. Disable OpenSSL embedding: when it's on, the build
# process of gRPC puts the OpenSSL static object files into the gRPC archive
# which causes link errors later when the agent is linked with the static
# OpenSSL library itself.
# Limit the number of threads used by make, as unlimited threads causes
# memory exhausted error on the Kokoro VM.
RUN git clone --depth=1 --recursive -b v1.28.1 https://github.com/grpc/grpc.git /tmp/grpc && \
cd /tmp/grpc && \
cd third_party/protobuf && \
./autogen.sh && \
./configure --with-pic CXXFLAGS="$(pkg-config --cflags protobuf)" LIBS="$(pkg-config --libs protobuf)" LDFLAGS="-Wl,--no-as-needed" && \
make -j4 && make install && ldconfig / && \
cd ../.. && \
CPPFLAGS="-I /usr/local/ssl/include" LDFLAGS="-L /usr/local/ssl/lib/ -Wl,--no-as-needed" make -j4 CONFIG=opt EMBED_OPENSSL=false V=1 HAS_SYSTEM_OPENSSL_NPN=0 && \
CPPFLAGS="-I /usr/local/ssl/include" LDFLAGS="-L /usr/local/ssl/lib/ -Wl,--no-as-needed" make CONFIG=opt EMBED_OPENSSL=false V=1 HAS_SYSTEM_OPENSSL_NPN=0 install && \
rm -rf /tmp/grpc
#
# See https://github.com/grpc/grpc/blob/v1.36.4/test/distrib/cpp/run_distrib_test_cmake_pkgconfig.sh
RUN git clone --depth=1 --recursive -b v1.36.4 https://github.com/grpc/grpc.git /tmp/grpc && \
cd /tmp/grpc/ && \
# Install protobuf
mkdir -p third_party/protobuf/cmake/build && \
(cd third_party/protobuf/cmake/build && \
cmake -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE -DCMAKE_BUILD_TYPE=Release .. && \
make -j4 install) && \
# Install gRPC
mkdir -p cmake/build && \
cd cmake/build && \
cmake \
-DOPENSSL_ROOT_DIR=/usr/local/ssl \
-DOPENSSL_INCLUDE_DIR=/usr/local/ssl/include \
-DOPENSSL_CRYPTO_LIB=/usr/local/ssl/lib \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local/grpc \
-DgRPC_INSTALL=ON \
-DgRPC_BUILD_TESTS=OFF \
-DgRPC_ABSL_PROVIDER=module \
-DgRPC_CARES_PROVIDER=module \
-DgRPC_RE2_PROVIDER=module \
-DgRPC_ZLIB_PROVIDER=module \
-DgRPC_PROTOBUF_PROVIDER=package \
-DgRPC_SSL_PROVIDER=package \
../.. && \
make -j4 install && \
cd ~ && rm -rf /tmp/grpc

ENV PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/usr/local/ssl/lib/pkgconfig:/usr/local/grpc/lib/pkgconfig:/usr/local/lib64/pkgconfig"
ENV PATH="${PATH}:/usr/local/grpc/bin"
32 changes: 16 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ CFLAGS = \
-Wno-array-bounds \
-g0 \
-DSTANDALONE_BUILD \
-D_GNU_SOURCE
-D_GNU_SOURCE \
$(shell pkg-config --cflags protobuf grpc)

ifeq ($(machine_type),$(filter $(machine_type),aarch64 arm64))
# Building on an ARM64 machine.
Expand All @@ -50,7 +51,7 @@ endif
SRC_ROOT_PATH=.

PROTOC ?= /usr/local/bin/protoc
PROTOC_GEN_GRPC ?= /usr/local/bin/grpc_cpp_plugin
GRPC_CPP_PLUGIN_PATH ?= /usr/local/grpc/bin/grpc_cpp_plugin

PROFILE_PROTO_PATH ?= third_party/perftools/profiles/proto
JAVA_AGENT_PATH ?= src
Expand Down Expand Up @@ -82,6 +83,8 @@ PROFILER_API_SOURCES = \
$(GENFILES_PATH)/google/api/client.pb.cc \
$(GENFILES_PATH)/google/api/http.pb.cc \
$(GENFILES_PATH)/google/api/launch_stage.pb.cc \
$(GENFILES_PATH)/google/api/resource.pb.cc \
$(GENFILES_PATH)/google/api/field_behavior.pb.cc \
$(GENFILES_PATH)/google/devtools/cloudprofiler/v2/profiler.grpc.pb.cc \
$(GENFILES_PATH)/google/devtools/cloudprofiler/v2/profiler.pb.cc \
$(GENFILES_PATH)/google/protobuf/duration.pb.cc \
Expand Down Expand Up @@ -160,7 +163,7 @@ HEADERS = \

VERSION_SCRIPT = $(JAVA_AGENT_PATH)/cloud_profiler_java_agent.lds
OPT_FLAGS = -O3
LDFLAGS = -static-libstdc++ -shared
LDFLAGS = -L/usr/local/lib -static-libstdc++ -shared $(shell pkg-config --libs --static protobuf grpc++)
LDS_FLAGS = -Wl,-z,defs -Wl,--version-script=$(VERSION_SCRIPT)

LIB_ROOT_PATH ?= /usr/local
Expand All @@ -176,17 +179,6 @@ LIBS1= \
$(LIB_ROOT_PATH)/lib/libglog.a \
$(LIB_ROOT_PATH)/lib/libgflags.a \

LIBS2= \
$(LIB_ROOT_PATH)/lib/libprotobuf.a \
$(LIB_ROOT_PATH)/ssl/lib/libssl.a \
$(LIB_ROOT_PATH)/ssl/lib/libcrypto.a \
-lz \

GRPC_LIBS= \
$(LIB_ROOT_PATH)/lib/libgrpc++.a \
$(LIB_ROOT_PATH)/lib/libgrpc.a \
$(LIB_ROOT_PATH)/lib/libgpr.a \

# Detect if running on Alpine and modify various flags
ifeq ("$(wildcard /etc/alpine-release)","/etc/alpine-release")
# musl only supports global dynamic tls model, and is documented as
Expand All @@ -212,7 +204,7 @@ clean:

$(TARGET_AGENT): $(SOURCES) $(HEADERS)
mkdir -p $(dir $@)
$(CC) $(INCLUDES) $(CFLAGS) $(OPT_FLAGS) $(LDFLAGS) $(SOURCES) $(LIBS1) $(GRPC_LIBS) $(LIBS2) -o $@ $(LDS_FLAGS)
$(CC) $(INCLUDES) $(CFLAGS) $(OPT_FLAGS) $(SOURCES) $(LIBS1) $(LDFLAGS) -o $@ $(LDS_FLAGS)

$(TARGET_NOTICES): $(JAVA_AGENT_PATH)/NOTICES
mkdir -p $(dir $@)
Expand All @@ -225,7 +217,7 @@ $(GENFILES_PATH)/%profiler.pb.h $(GENFILES_PATH)/%profiler.pb.cc : third_party/g
$(GENFILES_PATH)/%profiler.grpc.pb.h $(GENFILES_PATH)/%profiler.grpc.pb.cc : third_party/googleapis/%profiler.proto
mkdir -p $(dir $@)
$(PROTOC) -Ithird_party/googleapis -I$(PROTOBUF_INCLUDE_PATH) \
--plugin=protoc-gen-grpc=$(PROTOC_GEN_GRPC) --grpc_out=services_namespace=grpc:$(GENFILES_PATH) $<
--plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) --grpc_out=services_namespace=grpc:$(GENFILES_PATH) $<

$(GENFILES_PATH)/%annotations.pb.h $(GENFILES_PATH)/%annotations.pb.cc : third_party/googleapis/%annotations.proto
mkdir -p $(dir $@)
Expand All @@ -235,6 +227,14 @@ $(GENFILES_PATH)/%launch_stage.pb.h $(GENFILES_PATH)/%launch_stage.pb.cc : third
mkdir -p $(dir $@)
$(PROTOC) -Ithird_party/googleapis -I$(PROTOBUF_INCLUDE_PATH) --cpp_out=$(GENFILES_PATH) $<

$(GENFILES_PATH)/%resource.pb.h $(GENFILES_PATH)/%resource.pb.cc : third_party/googleapis/%resource.proto
mkdir -p $(dir $@)
$(PROTOC) -Ithird_party/googleapis -I$(PROTOBUF_INCLUDE_PATH) --cpp_out=$(GENFILES_PATH) $<

$(GENFILES_PATH)/%field_behavior.pb.h $(GENFILES_PATH)/%field_behavior.pb.cc : third_party/googleapis/%field_behavior.proto
mkdir -p $(dir $@)
$(PROTOC) -Ithird_party/googleapis -I$(PROTOBUF_INCLUDE_PATH) --cpp_out=$(GENFILES_PATH) $<

$(GENFILES_PATH)/%client.pb.h $(GENFILES_PATH)/%client.pb.cc : third_party/googleapis/%client.proto
mkdir -p $(dir $@)
$(PROTOC) -Ithird_party/googleapis -I$(PROTOBUF_INCLUDE_PATH) --cpp_out=$(GENFILES_PATH) $<
Expand Down
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ while getopts ":d:m:v:" opt; do
m)
TARGET=$OPTARG
if [[ "${TARGET}" == "arm64" ]]; then
if [[ "${MACHINE_TYPE}" != "aarch64" ]] || [[ "${MACHINE_TYPE}" != "arm64" ]]; then
if [[ "${MACHINE_TYPE}" != "aarch64" ]] && [[ "${MACHINE_TYPE}" != "arm64" ]]; then
echo "-m arm64 is supported only when running on an ARM64 system."
exit;
fi
Expand Down
1 change: 1 addition & 0 deletions src/cloud_env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <cstdlib>
#include <sstream>
#include <string>
#include <vector>

#include "src/clock.h"
#include "src/http.h"
Expand Down
8 changes: 7 additions & 1 deletion src/cloud_env.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#ifndef CLOUD_PROFILER_AGENT_JAVA_CLOUD_ENV_H_
#define CLOUD_PROFILER_AGENT_JAVA_CLOUD_ENV_H_

#include <string>

#include "src/globals.h"

namespace cloud {
Expand All @@ -29,6 +31,11 @@ class HTTPRequest;
class CloudEnv {
public:
CloudEnv();

// This type is neither copyable nor movable.
CloudEnv(const CloudEnv&) = delete;
CloudEnv& operator=(const CloudEnv&) = delete;

virtual ~CloudEnv() {}

// Returns the current cloud project ID.
Expand Down Expand Up @@ -68,7 +75,6 @@ class CloudEnv {
std::string zone_name_;
std::string service_;
std::string service_version_;
DISALLOW_COPY_AND_ASSIGN(CloudEnv);
};

// Returns the default instance of a cloud env object. The returned
Expand Down
10 changes: 5 additions & 5 deletions src/entry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <limits.h>

#include <string>
#include <vector>

#include "src/globals.h"
#include "src/string.h"
Expand Down Expand Up @@ -122,11 +123,10 @@ void JNICALL OnVMInit(jvmtiEnv *jvmti, JNIEnv *jni_env, jthread thread) {
}

if (FLAGS_cprof_enable_heap_sampling) {
// TODO: Allow using the JVM's stack tracer with a flag once
// we can get the current context in a cloud build.
google::javaprofiler::HeapMonitor::Enable(
jvmti, jni_env, FLAGS_cprof_heap_sampling_interval,
false /* use_jvm_trace */);
if (!google::javaprofiler::HeapMonitor::Enable(
jvmti, jni_env, FLAGS_cprof_heap_sampling_interval)) {
LOG(WARNING) << "Failed to start HeapMonitor.";
}
}

worker->Start(jni_env);
Expand Down
7 changes: 5 additions & 2 deletions src/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <jvmti.h>
#include <stdint.h>

#include <string>
#include <unordered_map>

#include "third_party/javaprofiler/jvmti_error.h"
Expand Down Expand Up @@ -103,6 +104,10 @@ class JvmtiScopedPtr {

JvmtiScopedPtr(jvmtiEnv *jvmti, T *ref) : jvmti_(jvmti), ref_(ref) {}

// This type is neither copyable nor movable.
JvmtiScopedPtr(const JvmtiScopedPtr &) = delete;
JvmtiScopedPtr &operator=(const JvmtiScopedPtr &) = delete;

~JvmtiScopedPtr() {
if (NULL != ref_) {
JVMTI_ERROR(jvmti_->Deallocate((unsigned char *)ref_));
Expand All @@ -121,8 +126,6 @@ class JvmtiScopedPtr {
private:
jvmtiEnv *jvmti_;
T *ref_;

DISALLOW_IMPLICIT_CONSTRUCTORS(JvmtiScopedPtr);
};

// Things that should probably be user-configurable
Expand Down
2 changes: 2 additions & 0 deletions src/http.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#include "src/http.h"

#include <string>

#include "curl/curl.h"

namespace cloud {
Expand Down
8 changes: 7 additions & 1 deletion src/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#ifndef CLOUD_PROFILER_AGENT_JAVA_HTTP_H_
#define CLOUD_PROFILER_AGENT_JAVA_HTTP_H_

#include <string>

#include "src/globals.h"

typedef void CURL;
Expand All @@ -31,6 +33,11 @@ const int kHTTPStatusOK = 200;
class HTTPRequest {
public:
HTTPRequest();

// This type is neither copyable nor movable.
HTTPRequest(const HTTPRequest&) = delete;
HTTPRequest& operator=(const HTTPRequest&) = delete;

virtual ~HTTPRequest();

virtual void AddAuthBearerHeader(const std::string& token);
Expand All @@ -51,7 +58,6 @@ class HTTPRequest {

CURL* curl_;
struct curl_slist* headers_;
DISALLOW_COPY_AND_ASSIGN(HTTPRequest);
};

} // namespace profiler
Expand Down
Loading