mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
introduce llvm/gwp-asan
This commit is contained in:
parent
f28b04fc59
commit
f5e736e240
1
contrib/CMakeLists.txt
vendored
1
contrib/CMakeLists.txt
vendored
@ -114,6 +114,7 @@ endif()
|
|||||||
|
|
||||||
add_contrib (llvm-project-cmake llvm-project)
|
add_contrib (llvm-project-cmake llvm-project)
|
||||||
add_contrib (libfuzzer-cmake llvm-project)
|
add_contrib (libfuzzer-cmake llvm-project)
|
||||||
|
add_contrib (gwpasan-cmake llvm-project)
|
||||||
add_contrib (libxml2-cmake libxml2)
|
add_contrib (libxml2-cmake libxml2)
|
||||||
|
|
||||||
add_contrib (aws-cmake
|
add_contrib (aws-cmake
|
||||||
|
41
contrib/gwpasan-cmake/CMakeLists.txt
Normal file
41
contrib/gwpasan-cmake/CMakeLists.txt
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
set(COMPILER_RT_GWP_ASAN_SRC_DIR "${ClickHouse_SOURCE_DIR}/contrib/llvm-project/compiler-rt/lib/gwp_asan")
|
||||||
|
|
||||||
|
set(GWP_ASAN_SOURCES
|
||||||
|
${COMPILER_RT_GWP_ASAN_SRC_DIR}/common.cpp
|
||||||
|
${COMPILER_RT_GWP_ASAN_SRC_DIR}/crash_handler.cpp
|
||||||
|
${COMPILER_RT_GWP_ASAN_SRC_DIR}/platform_specific/common_posix.cpp
|
||||||
|
${COMPILER_RT_GWP_ASAN_SRC_DIR}/platform_specific/guarded_pool_allocator_posix.cpp
|
||||||
|
${COMPILER_RT_GWP_ASAN_SRC_DIR}/platform_specific/mutex_posix.cpp
|
||||||
|
${COMPILER_RT_GWP_ASAN_SRC_DIR}/platform_specific/utilities_posix.cpp
|
||||||
|
${COMPILER_RT_GWP_ASAN_SRC_DIR}/guarded_pool_allocator.cpp
|
||||||
|
${COMPILER_RT_GWP_ASAN_SRC_DIR}/stack_trace_compressor.cpp
|
||||||
|
${COMPILER_RT_GWP_ASAN_SRC_DIR}/optional/options_parser.cpp
|
||||||
|
#PARENT_SCOPE
|
||||||
|
)
|
||||||
|
|
||||||
|
#set(GWP_ASAN_LIBS RTGwpAsan RTGwpAsanOptionsParser RTGwpAsanBacktraceLibc RTGwpAsanSegvHandler)
|
||||||
|
|
||||||
|
set(GWP_ASAN_HEADERS "${ClickHouse_SOURCE_DIR}/contrib/llvm-project/compiler-rt/lib")
|
||||||
|
|
||||||
|
#set(GWP_ASAN_HEADERS_FILES
|
||||||
|
# ${COMPILER_RT_GWP_ASAN_SRC_DIR}/common.h
|
||||||
|
# ${COMPILER_RT_GWP_ASAN_SRC_DIR}/crash_handler.h
|
||||||
|
# ${COMPILER_RT_GWP_ASAN_SRC_DIR}/definitions.h
|
||||||
|
# ${COMPILER_RT_GWP_ASAN_SRC_DIR}/guarded_pool_allocator.h
|
||||||
|
# ${COMPILER_RT_GWP_ASAN_SRC_DIR}/mutex.h
|
||||||
|
# ${COMPILER_RT_GWP_ASAN_SRC_DIR}/options.h
|
||||||
|
# ${COMPILER_RT_GWP_ASAN_SRC_DIR}/options.inc
|
||||||
|
# ${COMPILER_RT_GWP_ASAN_SRC_DIR}/platform_specific/guarded_pool_allocator_fuchsia.h
|
||||||
|
# ${COMPILER_RT_GWP_ASAN_SRC_DIR}/platform_specific/guarded_pool_allocator_posix.h
|
||||||
|
# ${COMPILER_RT_GWP_ASAN_SRC_DIR}/platform_specific/guarded_pool_allocator_tls.h
|
||||||
|
# ${COMPILER_RT_GWP_ASAN_SRC_DIR}/platform_specific/mutex_fuchsia.h
|
||||||
|
# ${COMPILER_RT_GWP_ASAN_SRC_DIR}/platform_specific/mutex_posix.h
|
||||||
|
# ${COMPILER_RT_GWP_ASAN_SRC_DIR}/stack_trace_compressor.h
|
||||||
|
# ${COMPILER_RT_GWP_ASAN_SRC_DIR}/utilities.h
|
||||||
|
# PARENT_SCOPE
|
||||||
|
#)
|
||||||
|
|
||||||
|
add_library(_gwp_asan ${GWP_ASAN_SOURCES})
|
||||||
|
#target_link_libraries (_gwp_asan INTERFACE ${GWP_ASAN_SOURCES})
|
||||||
|
target_include_directories (_gwp_asan SYSTEM PUBLIC ${GWP_ASAN_HEADERS})
|
||||||
|
add_library(ch_contrib::gwp_asan ALIAS _gwp_asan)
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <Common/StringUtils/StringUtils.h>
|
#include <Common/StringUtils/StringUtils.h>
|
||||||
#include <Common/getHashOfLoadedBinary.h>
|
#include <Common/getHashOfLoadedBinary.h>
|
||||||
|
#include <Common/gwp_asan.h>
|
||||||
#include <Common/IO.h>
|
#include <Common/IO.h>
|
||||||
|
|
||||||
#include <base/phdr_cache.h>
|
#include <base/phdr_cache.h>
|
||||||
@ -433,7 +434,6 @@ extern "C"
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/// This allows to implement assert to forbid initialization of a class in static constructors.
|
/// This allows to implement assert to forbid initialization of a class in static constructors.
|
||||||
/// Usage:
|
/// Usage:
|
||||||
///
|
///
|
||||||
@ -465,6 +465,8 @@ int main(int argc_, char ** argv_)
|
|||||||
/// It is needed because LLVM library clobbers it.
|
/// It is needed because LLVM library clobbers it.
|
||||||
std::set_new_handler(nullptr);
|
std::set_new_handler(nullptr);
|
||||||
|
|
||||||
|
Memory::initGWPAsan();
|
||||||
|
|
||||||
std::vector<char *> argv(argv_, argv_ + argc_);
|
std::vector<char *> argv(argv_, argv_ + argc_);
|
||||||
|
|
||||||
/// Print a basic help if nothing was matched
|
/// Print a basic help if nothing was matched
|
||||||
|
@ -310,6 +310,11 @@ if (TARGET ch_contrib::llvm)
|
|||||||
dbms_target_link_libraries (PUBLIC ch_contrib::llvm)
|
dbms_target_link_libraries (PUBLIC ch_contrib::llvm)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
if (TARGET ch_contrib::gwp_asan)
|
||||||
|
target_link_libraries (clickhouse_common_io PUBLIC ch_contrib::gwp_asan)
|
||||||
|
target_link_libraries (clickhouse_new_delete PRIVATE ch_contrib::gwp_asan)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Otherwise it will slow down stack traces printing too much.
|
# Otherwise it will slow down stack traces printing too much.
|
||||||
set_source_files_properties(
|
set_source_files_properties(
|
||||||
Common/Elf.cpp
|
Common/Elf.cpp
|
||||||
|
20
src/Common/gwp_asan.h
Normal file
20
src/Common/gwp_asan.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <base/defines.h>
|
||||||
|
|
||||||
|
#include <gwp_asan/guarded_pool_allocator.h>
|
||||||
|
#include <gwp_asan/optional/options_parser.h>
|
||||||
|
|
||||||
|
namespace Memory
|
||||||
|
{
|
||||||
|
|
||||||
|
static gwp_asan::GuardedPoolAllocator GuardedAlloc;
|
||||||
|
|
||||||
|
inline ALWAYS_INLINE void initGWPAsan()
|
||||||
|
{
|
||||||
|
gwp_asan::options::initOptions();
|
||||||
|
gwp_asan::options::Options &opts = gwp_asan::options::getOptions();
|
||||||
|
GuardedAlloc.init(opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <Common/Concepts.h>
|
#include <Common/Concepts.h>
|
||||||
#include <Common/CurrentMemoryTracker.h>
|
#include <Common/CurrentMemoryTracker.h>
|
||||||
|
#include <Common/gwp_asan.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#if USE_JEMALLOC
|
#if USE_JEMALLOC
|
||||||
@ -29,6 +30,21 @@ template <std::same_as<std::align_val_t>... TAlign>
|
|||||||
requires DB::OptionalArgument<TAlign...>
|
requires DB::OptionalArgument<TAlign...>
|
||||||
inline ALWAYS_INLINE void * newImpl(std::size_t size, TAlign... align)
|
inline ALWAYS_INLINE void * newImpl(std::size_t size, TAlign... align)
|
||||||
{
|
{
|
||||||
|
if (unlikely(GuardedAlloc.shouldSample()))
|
||||||
|
{
|
||||||
|
if constexpr (sizeof...(TAlign) == 1)
|
||||||
|
{
|
||||||
|
if (void * ptr = GuardedAlloc.allocate(size, alignToSizeT(align...)))
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (void * ptr = GuardedAlloc.allocate(size))
|
||||||
|
return ptr;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void * ptr = nullptr;
|
void * ptr = nullptr;
|
||||||
if constexpr (sizeof...(TAlign) == 1)
|
if constexpr (sizeof...(TAlign) == 1)
|
||||||
ptr = aligned_alloc(alignToSizeT(align...), size);
|
ptr = aligned_alloc(alignToSizeT(align...), size);
|
||||||
@ -44,16 +60,31 @@ inline ALWAYS_INLINE void * newImpl(std::size_t size, TAlign... align)
|
|||||||
|
|
||||||
inline ALWAYS_INLINE void * newNoExept(std::size_t size) noexcept
|
inline ALWAYS_INLINE void * newNoExept(std::size_t size) noexcept
|
||||||
{
|
{
|
||||||
|
if (unlikely(GuardedAlloc.shouldSample()))
|
||||||
|
{
|
||||||
|
if (void * ptr = GuardedAlloc.allocate(size))
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ALWAYS_INLINE void * newNoExept(std::size_t size, std::align_val_t align) noexcept
|
inline ALWAYS_INLINE void * newNoExept(std::size_t size, std::align_val_t align) noexcept
|
||||||
{
|
{
|
||||||
|
if (unlikely(GuardedAlloc.shouldSample()))
|
||||||
|
{
|
||||||
|
if (void * ptr = GuardedAlloc.allocate(size, alignToSizeT(align)))
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
return aligned_alloc(static_cast<size_t>(align), size);
|
return aligned_alloc(static_cast<size_t>(align), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ALWAYS_INLINE void deleteImpl(void * ptr) noexcept
|
inline ALWAYS_INLINE void deleteImpl(void * ptr) noexcept
|
||||||
{
|
{
|
||||||
|
if (unlikely(GuardedAlloc.pointerIsMine(ptr)))
|
||||||
|
{
|
||||||
|
GuardedAlloc.deallocate(ptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +97,12 @@ inline ALWAYS_INLINE void deleteSized(void * ptr, std::size_t size, TAlign... al
|
|||||||
if (unlikely(ptr == nullptr))
|
if (unlikely(ptr == nullptr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (unlikely(GuardedAlloc.pointerIsMine(ptr)))
|
||||||
|
{
|
||||||
|
GuardedAlloc.deallocate(ptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if constexpr (sizeof...(TAlign) == 1)
|
if constexpr (sizeof...(TAlign) == 1)
|
||||||
sdallocx(ptr, size, MALLOCX_ALIGN(alignToSizeT(align...)));
|
sdallocx(ptr, size, MALLOCX_ALIGN(alignToSizeT(align...)));
|
||||||
else
|
else
|
||||||
@ -122,6 +159,14 @@ template <std::same_as<std::align_val_t>... TAlign>
|
|||||||
requires DB::OptionalArgument<TAlign...>
|
requires DB::OptionalArgument<TAlign...>
|
||||||
inline ALWAYS_INLINE void untrackMemory(void * ptr [[maybe_unused]], std::size_t size [[maybe_unused]] = 0, TAlign... align [[maybe_unused]]) noexcept
|
inline ALWAYS_INLINE void untrackMemory(void * ptr [[maybe_unused]], std::size_t size [[maybe_unused]] = 0, TAlign... align [[maybe_unused]]) noexcept
|
||||||
{
|
{
|
||||||
|
if (unlikely(GuardedAlloc.pointerIsMine(ptr)))
|
||||||
|
{
|
||||||
|
if (!size)
|
||||||
|
size = GuardedAlloc.getSize(ptr);
|
||||||
|
CurrentMemoryTracker::free(size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#if USE_JEMALLOC
|
#if USE_JEMALLOC
|
||||||
|
Loading…
Reference in New Issue
Block a user