Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions make/autoconf/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,9 @@ JDKOPT_SETUP_ADDRESS_SANITIZER
# UndefinedBehaviorSanitizer
JDKOPT_SETUP_UNDEFINED_BEHAVIOR_SANITIZER

# LeakSanitizer
JDKOPT_SETUP_LEAK_SANITIZER

###############################################################################
#
# Check dependencies for external and internal libraries.
Expand Down
33 changes: 33 additions & 0 deletions make/autoconf/jdk-options.m4
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,39 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_ADDRESS_SANITIZER],
AC_SUBST(ASAN_ENABLED)
])

###############################################################################
#
# LeakSanitizer
#
AC_DEFUN_ONCE([JDKOPT_SETUP_LEAK_SANITIZER],
[
UTIL_ARG_ENABLE(NAME: lsan, DEFAULT: false, RESULT: LSAN_ENABLED,
DESC: [enable LeakSanitizer],
CHECK_AVAILABLE: [
AC_MSG_CHECKING([if LeakSanitizer (lsan) is available])
if test "x$TOOLCHAIN_TYPE" = "xgcc" ||
test "x$TOOLCHAIN_TYPE" = "xclang"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
AVAILABLE=false
fi
],
IF_ENABLED: [
LSAN_CFLAGS="-fsanitize=leak -fno-omit-frame-pointer -DLEAK_SANITIZER"
LSAN_LDFLAGS="-fsanitize=leak"
JVM_CFLAGS="$JVM_CFLAGS $LSAN_CFLAGS"
JVM_LDFLAGS="$JVM_LDFLAGS $LSAN_LDFLAGS"
CFLAGS_JDKLIB="$CFLAGS_JDKLIB $LSAN_CFLAGS"
CFLAGS_JDKEXE="$CFLAGS_JDKEXE $LSAN_CFLAGS"
CXXFLAGS_JDKLIB="$CXXFLAGS_JDKLIB $LSAN_CFLAGS"
CXXFLAGS_JDKEXE="$CXXFLAGS_JDKEXE $LSAN_CFLAGS"
LDFLAGS_JDKLIB="$LDFLAGS_JDKLIB $LSAN_LDFLAGS"
LDFLAGS_JDKEXE="$LDFLAGS_JDKEXE $LSAN_LDFLAGS"
])
AC_SUBST(LSAN_ENABLED)
])

###############################################################################
#
# UndefinedBehaviorSanitizer
Expand Down
3 changes: 3 additions & 0 deletions make/autoconf/spec.gmk.in
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,9 @@ JCOV_FILTERS=@JCOV_FILTERS@
# AddressSanitizer
ASAN_ENABLED:=@ASAN_ENABLED@

# LeakSanitizer
LSAN_ENABLED:=@LSAN_ENABLED@

# UndefinedBehaviorSanitizer
UBSAN_ENABLED:=@UBSAN_ENABLED@
UBSAN_CFLAGS:=@UBSAN_CFLAGS@
Expand Down
4 changes: 4 additions & 0 deletions make/common/modules/LauncherCommon.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ define SetupBuildLauncherBody
$1_EXTRA_FILES += $(TOPDIR)/make/data/asan/asan_default_options.c
endif

ifeq ($(LSAN_ENABLED), true)
$1_EXTRA_FILES += $(TOPDIR)/make/data/lsan/lsan_default_options.c
endif

$$(eval $$(call SetupJdkExecutable, BUILD_LAUNCHER_$1, \
NAME := $1, \
EXTRA_FILES := $$($1_EXTRA_FILES), \
Expand Down
14 changes: 11 additions & 3 deletions make/data/asan/asan_default_options.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, Google and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -50,8 +50,16 @@
// used. You can override these options by setting the environment variable ASAN_OPTIONS.
ATTRIBUTE_DEFAULT_VISIBILITY ATTRIBUTE_USED const char* __asan_default_options() {
return
#ifndef LEAK_SANITIZER
#ifdef LEAK_SANITIZER
"leak_check_at_exit=0,"
#else
// ASan bundles LSan, however we only support LSan when it is explicitly requested during
// configuration. Thus we disable it to match if it was not requested.
"detect_leaks=0,"
#endif
"handle_segv=0";
"print_suppressions=0,"
"handle_segv=0,"
// See https://github.com/google/sanitizers/issues/1322. Hopefully this is resolved
// at some point and we can remove this option.
"intercept_tls_get_addr=0";
}
2 changes: 1 addition & 1 deletion make/data/asan/asan_default_options.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, Google and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down
67 changes: 67 additions & 0 deletions make/data/lsan/lsan_default_options.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2023, Google and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

#ifndef LEAK_SANITIZER
#error "Build misconfigured, preprocessor macro LEAK_SANITIZER should be defined"
#endif

#ifndef __has_attribute
#define __has_attribute(x) 0
#endif

#if (defined(__GNUC__) && !defined(__clang__)) || __has_attribute(visibility)
#define ATTRIBUTE_DEFAULT_VISIBILITY __attribute__((visibility("default")))
#else
#define ATTRIBUTE_DEFAULT_VISIBILITY
#endif

#if (defined(__GNUC__) && !defined(__clang__)) || __has_attribute(used)
#define ATTRIBUTE_USED __attribute__((used))
#else
#define ATTRIBUTE_USED
#endif

// Override weak symbol exposed by LSan to override default options. This is called by LSan
// extremely early during library loading, before main is called. We need to override the default
// options because LSan will perform leak checking at program exit. Unfortunately Hotspot does not
// shutdown cleanly at the moment and some leaks occur, we want to ignore these. Instead we
// explicitly perform leak checking early during JVM shutdown.
ATTRIBUTE_DEFAULT_VISIBILITY ATTRIBUTE_USED const char* __lsan_default_options() {
return
"print_suppressions=0,"
"leak_check_at_exit=0,"
// See https://github.com/google/sanitizers/issues/1322. Hopefully this is resolved
// at some point and we can remove this option.
"intercept_tls_get_addr=0";
}

// Override weak symbol exposed by LSan to override default suppressions. This is called by LSan
// extremely early during library loading, before main is called.
ATTRIBUTE_DEFAULT_VISIBILITY ATTRIBUTE_USED const char* __lsan_default_suppressions() {
return
// Remove after JDK-8297688 is resolved.
"leak:^JLI_MemAlloc$\n"
"leak:^JLI_StringDup$\n";
}
30 changes: 30 additions & 0 deletions make/data/lsan/lsan_default_options.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2023, Google and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

extern "C" {

#include "./lsan_default_options.c"

} // extern "C"
4 changes: 4 additions & 0 deletions make/hotspot/lib/CompileGtest.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ ifeq ($(ASAN_ENABLED), true)
GTEST_LAUNCHER_SRC += $(TOPDIR)/make/data/asan/asan_default_options.cpp
endif

ifeq ($(LSAN_ENABLED), true)
GTEST_LAUNCHER_SRC += $(TOPDIR)/make/data/lsan/lsan_default_options.cpp
endif

# On Windows, there are no internal debug symbols so must set copying to true
# to get any at all.
ifeq ($(call isTargetOs, windows), true)
Expand Down
8 changes: 7 additions & 1 deletion make/test/JtregNativeHotspot.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -1521,7 +1521,13 @@ endif
ifeq ($(ASAN_ENABLED), true)
# Any executable which launches the JVM and uses a custom launcher needs to explicitly link in the
# default ASan options.
BUILD_HOTSPOT_JTREG_EXTRA_FILES := $(TOPDIR)/make/data/asan/asan_default_options.c
BUILD_HOTSPOT_JTREG_EXTRA_FILES += $(TOPDIR)/make/data/asan/asan_default_options.c
endif

ifeq ($(LSAN_ENABLED), true)
# Any executable which launches the JVM and uses a custom launcher needs to explicitly link in the
# default LSan options.
BUILD_HOTSPOT_JTREG_EXTRA_FILES += $(TOPDIR)/make/data/lsan/lsan_default_options.c
endif

# This evaluation is expensive and should only be done if this target was
Expand Down
8 changes: 7 additions & 1 deletion make/test/JtregNativeJdk.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,13 @@ endif
ifeq ($(ASAN_ENABLED), true)
# Any executable which launches the JVM and uses a custom launcher needs to explicitly link in the
# default ASan options.
BUILD_JDK_JTREG_EXTRA_FILES := $(TOPDIR)/make/data/asan/asan_default_options.c
BUILD_JDK_JTREG_EXTRA_FILES += $(TOPDIR)/make/data/asan/asan_default_options.c
endif

ifeq ($(LSAN_ENABLED), true)
# Any executable which launches the JVM and uses a custom launcher needs to explicitly link in the
# default LSan options.
BUILD_JDK_JTREG_EXTRA_FILES += $(TOPDIR)/make/data/lsan/lsan_default_options.c
endif

# This evaluation is expensive and should only be done if this target was
Expand Down
3 changes: 3 additions & 0 deletions src/hotspot/share/c1/c1_Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/vm_version.hpp"
#include "sanitizers/leak.hpp"
#include "utilities/bitMap.inline.hpp"
#include "utilities/macros.hpp"

Expand All @@ -50,6 +51,8 @@ Compiler::Compiler() : AbstractCompiler(compiler_c1) {
void Compiler::init_c1_runtime() {
BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob();
Arena* arena = new (mtCompiler) Arena(mtCompiler);
// Ignore leaked arena, it is used by ValueType and Interval during initialization.
LSAN_IGNORE_OBJECT(arena);
Runtime1::initialize(buffer_blob);
FrameMap::initialize();
// initialize data structures
Expand Down
3 changes: 3 additions & 0 deletions src/hotspot/share/cds/metaspaceShared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
#include "runtime/sharedRuntime.hpp"
#include "runtime/vmThread.hpp"
#include "runtime/vmOperations.hpp"
#include "sanitizers/leak.hpp"
#include "services/memTracker.hpp"
#include "utilities/align.hpp"
#include "utilities/bitMap.inline.hpp"
Expand Down Expand Up @@ -990,6 +991,8 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() {
bool dynamic_mapped = (dynamic_mapinfo != nullptr && dynamic_mapinfo->is_mapped());
char* cds_base = static_mapinfo->mapped_base();
char* cds_end = dynamic_mapped ? dynamic_mapinfo->mapped_end() : static_mapinfo->mapped_end();
// Register CDS memory region with LSan.
LSAN_REGISTER_ROOT_REGION(cds_base, cds_end - cds_base);
set_shared_metaspace_range(cds_base, static_mapinfo->mapped_end(), cds_end);
_relocation_delta = static_mapinfo->relocation_delta();
_requested_base_address = static_mapinfo->requested_base_address();
Expand Down
6 changes: 6 additions & 0 deletions src/hotspot/share/code/codeCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#include "runtime/os.inline.hpp"
#include "runtime/safepointVerifiers.hpp"
#include "runtime/vmThread.hpp"
#include "sanitizers/leak.hpp"
#include "services/memoryService.hpp"
#include "utilities/align.hpp"
#include "utilities/vmError.hpp"
Expand Down Expand Up @@ -329,6 +330,9 @@ void CodeCache::initialize_heaps() {
ReservedSpace non_method_space = rest.first_part(non_nmethod_size);
ReservedSpace non_profiled_space = rest.last_part(non_nmethod_size);

// Register CodeHeaps with LSan as we sometimes embed pointers to malloc memory.
LSAN_REGISTER_ROOT_REGION(rs.base(), rs.size());

// Non-nmethods (stubs, adapters, ...)
add_heap(non_method_space, "CodeHeap 'non-nmethods'", CodeBlobType::NonNMethod);
// Tier 2 and tier 3 (profiled) methods
Expand Down Expand Up @@ -1194,6 +1198,8 @@ void CodeCache::initialize() {
FLAG_SET_ERGO(ProfiledCodeHeapSize, 0);
FLAG_SET_ERGO(NonProfiledCodeHeapSize, 0);
ReservedCodeSpace rs = reserve_heap_memory(ReservedCodeCacheSize);
// Register CodeHeaps with LSan as we sometimes embed pointers to malloc memory.
LSAN_REGISTER_ROOT_REGION(rs.base(), rs.size());
add_heap(rs, "CodeCache", CodeBlobType::All);
}

Expand Down
7 changes: 7 additions & 0 deletions src/hotspot/share/code/compiledIC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "runtime/safepoint.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "sanitizers/leak.hpp"
#include "utilities/events.hpp"


Expand Down Expand Up @@ -272,6 +273,9 @@ bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod
needs_ic_stub_refill = true;
return false;
}
// LSan appears unable to follow malloc-based memory consistently when embedded as an immediate
// in generated machine code. So we have to ignore it.
LSAN_IGNORE_OBJECT(holder);
} else {
assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable");
// Can be different than selected_method->vtable_index(), due to package-private etc.
Expand Down Expand Up @@ -442,6 +446,9 @@ bool CompiledIC::set_to_monomorphic(CompiledICInfo& info) {
delete holder;
return false;
}
// LSan appears unable to follow malloc-based memory consistently when embedded as an
// immediate in generated machine code. So we have to ignore it.
LSAN_IGNORE_OBJECT(holder);
if (TraceICs) {
ResourceMark rm(thread);
tty->print_cr ("IC@" INTPTR_FORMAT ": monomorphic to interpreter via icholder ", p2i(instruction_address()));
Expand Down
9 changes: 9 additions & 0 deletions src/hotspot/share/memory/metaspace/virtualSpaceNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
#include "sanitizers/address.hpp"
#include "sanitizers/leak.hpp"
#include "services/memTracker.hpp"
#include "utilities/align.hpp"
#include "utilities/debug.hpp"
Expand Down Expand Up @@ -239,6 +240,10 @@ VirtualSpaceNode::VirtualSpaceNode(ReservedSpace rs, bool owns_rs, CommitLimiter
// Poison the memory region. It will be unpoisoned later on a per-chunk base for chunks that are
// handed to arenas.
ASAN_POISON_MEMORY_REGION(rs.base(), rs.size());

// Register memory region related to Metaspace. The Metaspace contains lots of pointers to malloc
// memory.
LSAN_REGISTER_ROOT_REGION(rs.base(), rs.size());
}

// Create a node of a given size (it will create its own space).
Expand Down Expand Up @@ -270,11 +275,15 @@ VirtualSpaceNode* VirtualSpaceNode::create_node(ReservedSpace rs, CommitLimiter*
VirtualSpaceNode::~VirtualSpaceNode() {
DEBUG_ONLY(verify_locked();)

// Unregister memory region related to Metaspace.
LSAN_UNREGISTER_ROOT_REGION(_rs.base(), _rs.size());

// Undo the poisoning before potentially unmapping memory. This ensures that future mappings at
// the same address do not unexpectedly fail with use-after-poison.
ASAN_UNPOISON_MEMORY_REGION(_rs.base(), _rs.size());

UL(debug, ": dies.");

if (_owns_rs) {
_rs.release();
}
Expand Down
7 changes: 6 additions & 1 deletion src/hotspot/share/memory/universe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
#include "runtime/jniHandles.hpp"
#include "runtime/threads.hpp"
#include "runtime/timerTrace.hpp"
#include "sanitizers/leak.hpp"
#include "services/memoryService.hpp"
#include "utilities/align.hpp"
#include "utilities/autoRestore.hpp"
Expand Down Expand Up @@ -751,7 +752,11 @@ bool Universe::contains_non_oop_word(void* p) {
}

static void initialize_global_behaviours() {
CompiledICProtectionBehaviour::set_current(new DefaultICProtectionBehaviour());
DefaultICProtectionBehaviour* protection_behavior = new DefaultICProtectionBehaviour();
// Ignore leak of DefaultICProtectionBehaviour. It is overriden by some GC implementations and the
// pointer is leaked once.
LSAN_IGNORE_OBJECT(protection_behavior);
CompiledICProtectionBehaviour::set_current(protection_behavior);
}

jint universe_init() {
Expand Down
Loading