提交 682d0b28 编写于 作者: S Shreedhar Hardikar

Allow overriding assert() functionality in libgpcodegen in DEBUG mode

 * Support assert overriding in Linux and OSX.
 * Add checks in CMakelists.txt in case LLVM libraries already override
   assert()
Signed-off-by: NNikos Armenatzoglou <nikos.armenatzoglou@gmail.com>
上级 3209258a
......@@ -61,19 +61,24 @@ if (COMPILER_HAS_WNO_C99_EXTENSIONS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-register")
endif()
# Turn on the CODEGEN_DEBUG flag if this is a debug build.
macro (ADD_DEBUG_COMPILE_DEFINITION SYMBOL)
if (CMAKE_MAJOR_VERSION GREATER 2)
cmake_policy(SET CMP0043 NEW)
set_property(
DIRECTORY
APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:CODEGEN_DEBUG>
APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:${SYMBOL}>
)
else()
set_property(
DIRECTORY
APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG CODEGEN_DEBUG
APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG ${SYMBOL}
)
endif()
endmacro()
# Turn on the CODEGEN_DEBUG flag if this is a debug build.
ADD_DEBUG_COMPILE_DEFINITION(CODEGEN_DEBUG)
# Check for POSIX I/O syscalls needed by TemporaryFile.
include(CheckCXXSymbolExists)
......@@ -136,6 +141,7 @@ add_library(gpcodegen SHARED
utils/clang_compiler.cc
utils/codegen_utils.cc
utils/gp_codegen_utils.cc
utils/gp_assert.cc
codegen_interface.cc
codegen_manager.cc
......@@ -160,8 +166,8 @@ else()
endif()
# By default, the Darwin linker throws an error if there are any undefined
# references in a dynamic library. Instead, it should wait till it's linked
# back with the postgres binary.
# references in a dynamic library. Instead, it should wait till it's loaded
# by the postgres binary.
if(APPLE)
set(WL_UNDEFINED_DYNLOOKUP "-Wl,-undefined -Wl,dynamic_lookup")
else()
......@@ -185,6 +191,51 @@ else()
target_link_libraries(gpcodegen ${WL_START_GROUP} ${codegen_llvm_libs} ${WL_END_GROUP})
endif()
# This macro checks to see if the given C symbol is defined in the given LIBRARY. A library with
# an appropriate name is searched for in the LIBPATH. VARIABLE is set to true if the symbol is
# found defined as a type in (T in the output of nm) in the library, or set false otherwise.
macro(CHECK_SYMBOL_DEFINED LIBRARY CSYMBOL LIBPATH VARIABLE)
find_library(LIBLOCATION ${LIBRARY} ${LIBPATH})
if(LIBLOCATION STREQUAL "LIBLOCATION-NOTFOUND")
message(FATAL_ERROR "${LIBRARY} not found in ${LIBPATH}.")
endif()
find_program(NM_BIN "nm")
execute_process(COMMAND ${NM_BIN} ${LIBLOCATION}
COMMAND grep "T" # Symbol is defined
COMMAND grep ${CSYMBOL}
RESULT_VARIABLE RETURN_CODE
OUTPUT_QUIET)
if(${RETURN_CODE} EQUAL 0) # One or more lines were selected
set(VARIABLE true)
elseif(${RETURN_CODE} EQUAL 1) # No lines were selected.
set(VARIABLE false)
else()
message(FATAL_ERROR "Attempted to determine it ${CSYMBOL} is defined in ${LIBLOCATION} "
"but the execution failed. Return code = ${RETURN_CODE}")
endif()
endmacro()
if(APPLE)
set(ASSERT_FUNCTION_TO_OVERRIDE "__assert_rtn")
elseif(UNIX)
set(ASSERT_FUNCTION_TO_OVERRIDE "__assert_fail")
endif()
if(CMAKE_BUILD_TYPE STREQUAL Debug)
# Since we want to override assert handling in GPDB, we need to make sure
# that LLVM and Clang libraries we depend on haven't done that already
# If they do, we simply report a WARNING, and skip assert overriding in GPDB.
CHECK_SYMBOL_DEFINED(LLVMSupport ${ASSERT_FUNCTION_TO_OVERRIDE} ${LLVM_LIBRARY_DIRS} LLVM_ASSERT_REDEFINED)
if (LLVM_ASSERT_REDEFINED)
message(WARNING
"Found ${ASSERT_FUNCTION_TO_OVERRIDE} redefined in LLVM libraries. "
"Disabling GPDB codegen assert handling! "
"To enable this, rebuild LLVM libraries with -DLLVM_ENABLE_CRASH_OVERRIDES=off.")
else()
ADD_DEBUG_COMPILE_DEFINITION(CODEGEN_GPDB_ASSERT_HANDLING)
endif()
endif()
get_filename_component(full_install_name_dir "${CMAKE_INSTALL_PREFIX}/lib" ABSOLUTE)
set_target_properties(
gpcodegen PROPERTIES
......
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2016 Pivotal Software, Inc.
//
// @filename:
// gp_assert.cc
//
// @doc:
// Implementation of lower level assert methods to override C++ assert()
// functionality to pass any errors to GPDB.
//
//---------------------------------------------------------------------------
#ifdef CODEGEN_GPDB_ASSERT_HANDLING
extern "C" {
#include <utils/elog.h>
// Overload assert handling from LLVM, and pass any error messages to GPDB.
// LLVM has a custom implementation of __assert_rtn, only compiled
// on OSX. To prevent naming conflicts when building GPDB, LLVM should
// be built with -DLLVM_ENABLE_CRASH_OVERRIDES=off
//
// (Refer http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20130826/186121.html)
#ifdef __APPLE__
void __assert_rtn(const char *func,
const char *file,
int line,
const char *expr) {
#elif __linux__
void __assert_fail(const char * expr,
const char * file,
unsigned int line,
const char * func) {
#endif
if (!func) {
func = "";
}
errstart(ERROR, file, line, func, TEXTDOMAIN);
errfinish(errcode(ERRCODE_INTERNAL_ERROR),
errmsg("C++ assertion failed: \"%s\"",
expr));
// Normal execution beyond this point is unsafe
}
}
#endif // CODEGEN_GPDB_ASSERT_HANDLING
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册