Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
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
5 changes: 5 additions & 0 deletions bazel/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ config_setting(
values = {"define": "tcmalloc=disabled"},
)

config_setting(
Comment thread
jmarantz marked this conversation as resolved.
name = "debug_memory",
values = {"define": "debug_memory=enabled"},
Comment thread
jmarantz marked this conversation as resolved.
Outdated
)

config_setting(
name = "disable_signal_trace",
values = {"define": "signal_trace=disabled"},
Expand Down
5 changes: 5 additions & 0 deletions bazel/envoy_build_system.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ def envoy_copts(repository, test = False):
}) + select({
repository + "//bazel:disable_tcmalloc": ["-DABSL_MALLOC_HOOK_MMAP_DISABLE"],
"//conditions:default": ["-DTCMALLOC"],
}) + select({
repository + "//bazel:debug_memory": ["-DENVOY_MEMORY_DEBUG_ENABLED=1"],
"//conditions:default": [],
}) + select({
repository + "//bazel:disable_signal_trace": [],
"//conditions:default": ["-DENVOY_HANDLE_SIGNALS"],
Expand Down Expand Up @@ -165,6 +168,7 @@ def envoy_external_dep_path(dep):
def tcmalloc_external_dep(repository):
return select({
repository + "//bazel:disable_tcmalloc": None,
repository + "//bazel:debug_memory": envoy_external_dep_path("tcmalloc_debug"),
"//conditions:default": envoy_external_dep_path("tcmalloc_and_profiler"),
})

Expand All @@ -174,6 +178,7 @@ def tcmalloc_external_dep(repository):
def tcmalloc_external_deps(repository):
return select({
repository + "//bazel:disable_tcmalloc": [],
repository + "//bazel:debug_memory": [envoy_external_dep_path("tcmalloc_debug")],
"//conditions:default": [envoy_external_dep_path("tcmalloc_and_profiler")],
})

Expand Down
1 change: 1 addition & 0 deletions bazel/target_recipes.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ TARGET_RECIPES = {
"benchmark": "benchmark",
"event": "libevent",
"tcmalloc_and_profiler": "gperftools",
"tcmalloc_debug": "gperftools",
Comment thread
jmarantz marked this conversation as resolved.
"luajit": "luajit",
"nghttp2": "nghttp2",
"yaml_cpp": "yaml-cpp",
Expand Down
7 changes: 7 additions & 0 deletions ci/prebuilt/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ cc_library(
strip_include_prefix = "thirdparty_build/include",
)

cc_library(
name = "tcmalloc_debug",
srcs = ["thirdparty_build/lib/libtcmalloc_debug.a"],
hdrs = glob(["thirdparty_build/include/gperftools/**/*.h"]),
strip_include_prefix = "thirdparty_build/include",
)

cc_library(
name = "yaml_cpp",
srcs = select({
Expand Down
2 changes: 1 addition & 1 deletion source/common/profiler/profiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include <string>

#ifdef TCMALLOC
#ifdef PROFILER_AVAILABLE

#include "gperftools/heap-profiler.h"
#include "gperftools/profiler.h"
Expand Down
4 changes: 4 additions & 0 deletions source/common/profiler/profiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

#include <string>

#if defined(TCMALLOC) && !defined(ENVOY_MEMORY_DEBUG_ENABLED)
Comment thread
jmarantz marked this conversation as resolved.
#define PROFILER_AVAILABLE
#endif

namespace Envoy {
namespace Profiler {

Expand Down
15 changes: 15 additions & 0 deletions test/common/memory/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
licenses(["notice"]) # Apache 2

load(
"//bazel:envoy_build_system.bzl",
"envoy_cc_test",
"envoy_package",
)

envoy_package()

envoy_cc_test(
name = "debug_test",
srcs = ["debug_test.cc"],
deps = ["//source/common/memory:stats_lib"],
)
38 changes: 38 additions & 0 deletions test/common/memory/debug_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "common/memory/stats.h"

#include "gtest/gtest.h"

namespace Envoy {
namespace Memory {

#ifdef ENVOY_MEMORY_DEBUG_ENABLED

constexpr int ArraySize = 10;

struct MyStruct {
MyStruct() : x_(0) {} // words_ is uninitialized; will have whatever allocator left there.
uint64_t x_;
uint64_t words_[ArraySize];
};

TEST(MemoryDebug, ByteSize) {
uint64_t before = Stats::totalCurrentlyAllocated();
auto ptr = std::make_unique<MyStruct>();
uint64_t after = Stats::totalCurrentlyAllocated();
EXPECT_LE(sizeof(MyStruct), after - before);
}

TEST(MemoryDebug, ScribbleOnNew) {
auto ptr = std::make_unique<MyStruct>();
for (int i = 0; i < ArraySize; ++i) {
// This is the pattern written by tcmalloc's debug library.
EXPECT_EQ(0xabababababababab, ptr->words_[i]);
}
}
Comment thread
jmarantz marked this conversation as resolved.

TEST(MemoryDebug, ZeroByteAlloc) { auto ptr = std::make_unique<uint8_t[]>(0); }

#endif // ENVOY_MEMORY_DEBUG_ENABLED

} // namespace Memory
} // namespace Envoy
2 changes: 1 addition & 1 deletion test/common/stats/stat_test_utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ bool hasDeterministicMallocStats() {
// library for Envoy is TCMALLOC that's what we test for here. If we switch
// to a different malloc library than we'd have to re-evaluate all the
// thresholds in the tests referencing hasDeterministicMallocStats().
#ifdef TCMALLOC
#if defined(TCMALLOC) && !defined(ENVOY_MEMORY_DEBUG_ENABLED)
const size_t start_mem = Memory::Stats::totalCurrentlyAllocated();
std::unique_ptr<char[]> data(new char[10000]);
const size_t end_mem = Memory::Stats::totalCurrentlyAllocated();
Expand Down
8 changes: 4 additions & 4 deletions test/integration/integration_admin_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -391,9 +391,6 @@ TEST_P(IntegrationAdminTest, AdminOnDestroyCallbacks) {
EXPECT_EQ(test_server_->server().statsFlushInterval(), std::chrono::milliseconds(5000));
}

// Successful call to startProfiler requires tcmalloc.
#ifdef TCMALLOC

TEST_P(IntegrationAdminTest, AdminCpuProfilerStart) {
config_helper_.addConfigModifier([&](envoy::config::bootstrap::v2::Bootstrap& bootstrap) -> void {
auto* admin = bootstrap.mutable_admin();
Expand All @@ -404,14 +401,17 @@ TEST_P(IntegrationAdminTest, AdminCpuProfilerStart) {
BufferingStreamDecoderPtr response = IntegrationUtil::makeSingleRequest(
lookupPort("admin"), "POST", "/cpuprofiler?enable=y", "", downstreamProtocol(), version_);
EXPECT_TRUE(response->complete());
#ifdef PROFILER_AVAILABLE
EXPECT_STREQ("200", response->headers().Status()->value().c_str());
#else
EXPECT_STREQ("500", response->headers().Status()->value().c_str());
#endif

response = IntegrationUtil::makeSingleRequest(
lookupPort("admin"), "POST", "/cpuprofiler?enable=n", "", downstreamProtocol(), version_);
EXPECT_TRUE(response->complete());
EXPECT_STREQ("200", response->headers().Status()->value().c_str());
}
#endif

class IntegrationAdminIpv4Ipv6Test : public HttpIntegrationTest, public testing::Test {
public:
Expand Down
16 changes: 10 additions & 6 deletions test/server/http/admin_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -622,22 +622,26 @@ class AdminInstanceTest : public testing::TestWithParam<Network::Address::IpVers
INSTANTIATE_TEST_CASE_P(IpVersions, AdminInstanceTest,
testing::ValuesIn(TestEnvironment::getIpVersionsForTest()),
TestUtility::ipTestParamsToString);
// Can only get code coverage of AdminImpl::handlerCpuProfiler stopProfiler with
// a real profiler linked in (successful call to startProfiler). startProfiler
// requies tcmalloc.
#ifdef TCMALLOC

TEST_P(AdminInstanceTest, AdminProfiler) {
Buffer::OwnedImpl data;
Http::HeaderMapImpl header_map;

// Can only get code coverage of AdminImpl::handlerCpuProfiler stopProfiler with
// a real profiler linked in (successful call to startProfiler).
#ifdef PROFILER_AVAILABLE
EXPECT_EQ(Http::Code::OK, postCallback("/cpuprofiler?enable=y", header_map, data));
EXPECT_TRUE(Profiler::Cpu::profilerEnabled());
#else
EXPECT_EQ(Http::Code::InternalServerError,
postCallback("/cpuprofiler?enable=y", header_map, data));
EXPECT_FALSE(Profiler::Cpu::profilerEnabled());
#endif

EXPECT_EQ(Http::Code::OK, postCallback("/cpuprofiler?enable=n", header_map, data));
EXPECT_FALSE(Profiler::Cpu::profilerEnabled());
}

#endif

TEST_P(AdminInstanceTest, MutatesErrorWithGet) {
Buffer::OwnedImpl data;
Http::HeaderMapImpl header_map;
Expand Down