mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
Enabled line numbers in stack traces
This commit is contained in:
parent
15dc6d1818
commit
372c4d89b2
@ -106,6 +106,10 @@ endif ()
|
||||
if (COMPILER_CLANG)
|
||||
# clang: warning: argument unused during compilation: '-specs=/usr/share/dpkg/no-pie-compile.specs' [-Wunused-command-line-argument]
|
||||
set (COMMON_WARNING_FLAGS "${COMMON_WARNING_FLAGS} -Wno-unused-command-line-argument")
|
||||
# generate ranges for fast "addr2line" search
|
||||
if (NOT CMAKE_BUILD_TYPE_UC STREQUAL "RELEASE")
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -gdwarf-aranges")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
option (ENABLE_TESTS "Enables tests" ON)
|
||||
|
@ -159,6 +159,11 @@ if (OS_FREEBSD)
|
||||
target_compile_definitions (clickhouse_common_io PUBLIC CLOCK_MONOTONIC_COARSE=CLOCK_MONOTONIC_FAST)
|
||||
endif ()
|
||||
|
||||
if (USE_UNWIND)
|
||||
target_compile_definitions (clickhouse_common_io PRIVATE USE_UNWIND=1)
|
||||
target_include_directories (clickhouse_common_io SYSTEM BEFORE PRIVATE ${UNWIND_INCLUDE_DIR})
|
||||
endif ()
|
||||
|
||||
add_subdirectory(src/Common/ZooKeeper)
|
||||
add_subdirectory(src/Common/Config)
|
||||
|
||||
|
@ -183,66 +183,6 @@ void skipPadding(std::string_view & sp, const char * start, size_t alignment)
|
||||
}
|
||||
}
|
||||
|
||||
// Simplify a path -- as much as we can while not moving data around...
|
||||
/*void simplifyPath(std::string_view & sp)
|
||||
{
|
||||
// Strip leading slashes and useless patterns (./), leaving one initial
|
||||
// slash.
|
||||
for (;;)
|
||||
{
|
||||
if (sp.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Strip leading slashes, leaving one.
|
||||
while (sp.startsWith("//"))
|
||||
{
|
||||
sp.remove_prefix(1);
|
||||
}
|
||||
|
||||
if (sp.startsWith("/./"))
|
||||
{
|
||||
// Note 2, not 3, to keep it absolute
|
||||
sp.remove_prefix(2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sp.removePrefix("./"))
|
||||
{
|
||||
// Also remove any subsequent slashes to avoid making this path absolute.
|
||||
while (sp.startsWith('/'))
|
||||
{
|
||||
sp.remove_prefix(1);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Strip trailing slashes and useless patterns (/.).
|
||||
for (;;)
|
||||
{
|
||||
if (sp.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Strip trailing slashes, except when this is the root path.
|
||||
while (sp.size() > 1 && sp.removeSuffix('/'))
|
||||
{
|
||||
}
|
||||
|
||||
if (sp.removeSuffix("/."))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -271,10 +211,6 @@ Dwarf::Path::Path(std::string_view baseDir, std::string_view subDir, std::string
|
||||
baseDir_ = {}; // subDir_ is absolute
|
||||
}
|
||||
|
||||
// simplifyPath(baseDir_);
|
||||
// simplifyPath(subDir_);
|
||||
// simplifyPath(file_);
|
||||
|
||||
// Make sure it's never the case that baseDir_ is empty, but subDir_ isn't.
|
||||
if (baseDir_.empty())
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include <Poco/Exception.h>
|
||||
|
||||
#include <common/StackTrace.h>
|
||||
#include <Common/StackTrace.h>
|
||||
|
||||
namespace Poco { class Logger; }
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <common/Pipe.h>
|
||||
#include <common/phdr_cache.h>
|
||||
#include <common/config_common.h>
|
||||
#include <common/StackTrace.h>
|
||||
#include <Common/StackTrace.h>
|
||||
#include <common/StringRef.h>
|
||||
#include <common/logger_useful.h>
|
||||
#include <Common/CurrentThread.h>
|
||||
|
@ -1,16 +1,16 @@
|
||||
#include <common/StackTrace.h>
|
||||
#include <common/SimpleCache.h>
|
||||
#include <common/demangle.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <cxxabi.h>
|
||||
#include <execinfo.h>
|
||||
#include <Common/StackTrace.h>
|
||||
#include <Common/SymbolIndex.h>
|
||||
#include <Common/Dwarf.h>
|
||||
#include <Common/Elf.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <filesystem>
|
||||
#include <unordered_map>
|
||||
#include <cstring>
|
||||
|
||||
#if USE_UNWIND
|
||||
#define UNW_LOCAL_ONLY
|
||||
#include <libunwind.h>
|
||||
#endif
|
||||
|
||||
std::string signalToErrorMessage(int sig, const siginfo_t & info, const ucontext_t & context)
|
||||
{
|
||||
@ -168,9 +168,9 @@ void * getCallerAddress(const ucontext_t & context)
|
||||
#endif
|
||||
#elif defined(__aarch64__)
|
||||
return reinterpret_cast<void *>(context.uc_mcontext.pc);
|
||||
#endif
|
||||
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
StackTrace::StackTrace()
|
||||
@ -195,6 +195,12 @@ StackTrace::StackTrace(NoCapture)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#if USE_UNWIND
|
||||
extern "C" int unw_backtrace(void **, int);
|
||||
#endif
|
||||
|
||||
|
||||
void StackTrace::tryCapture()
|
||||
{
|
||||
size = 0;
|
||||
@ -227,50 +233,43 @@ std::string StackTrace::toStringImpl(const Frames & frames, size_t size)
|
||||
if (size == 0)
|
||||
return "<Empty trace>";
|
||||
|
||||
char ** symbols = backtrace_symbols(frames.data(), size);
|
||||
if (!symbols)
|
||||
return "<Invalid trace>";
|
||||
const DB::SymbolIndex & symbol_index = DB::SymbolIndex::instance();
|
||||
std::unordered_map<std::string, DB::Dwarf> dwarfs;
|
||||
|
||||
std::stringstream backtrace;
|
||||
try
|
||||
std::stringstream out;
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
for (size_t i = 0; i < size; i++)
|
||||
out << "#" << i << " " << frames[i] << " ";
|
||||
auto symbol = symbol_index.findSymbol(frames[i]);
|
||||
if (symbol)
|
||||
{
|
||||
/// We do "demangling" of names. The name is in parenthesis, before the '+' character.
|
||||
|
||||
char * name_start = nullptr;
|
||||
char * name_end = nullptr;
|
||||
std::string demangled_name;
|
||||
int status = 0;
|
||||
|
||||
if (nullptr != (name_start = strchr(symbols[i], '('))
|
||||
&& nullptr != (name_end = strchr(name_start, '+')))
|
||||
{
|
||||
++name_start;
|
||||
*name_end = '\0';
|
||||
demangled_name = demangle(name_start, status);
|
||||
*name_end = '+';
|
||||
}
|
||||
|
||||
backtrace << i << ". ";
|
||||
|
||||
if (0 == status && name_start && name_end)
|
||||
{
|
||||
backtrace.write(symbols[i], name_start - symbols[i]);
|
||||
backtrace << demangled_name << name_end;
|
||||
}
|
||||
else
|
||||
backtrace << symbols[i];
|
||||
|
||||
backtrace << std::endl;
|
||||
out << demangle(symbol->name, status);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
free(symbols);
|
||||
throw;
|
||||
else
|
||||
out << "?";
|
||||
|
||||
out << " ";
|
||||
|
||||
if (auto object = symbol_index.findObject(frames[i]))
|
||||
{
|
||||
if (std::filesystem::exists(object->name))
|
||||
{
|
||||
auto dwarf_it = dwarfs.try_emplace(object->name, *object->elf).first;
|
||||
|
||||
DB::Dwarf::LocationInfo location;
|
||||
if (dwarf_it->second.findAddress(uintptr_t(object->address_begin) + uintptr_t(frames[i]), location, DB::Dwarf::LocationInfoMode::FAST))
|
||||
out << location.file.toString() << ":" << location.line;
|
||||
else
|
||||
out << object->name;
|
||||
}
|
||||
}
|
||||
else
|
||||
out << "?";
|
||||
|
||||
out << "\n";
|
||||
}
|
||||
|
||||
free(symbols);
|
||||
return backtrace.str();
|
||||
return out.str();
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
#include <Common/SymbolIndex.h>
|
||||
#include <Common/Elf.h>
|
||||
#include <common/demangle.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <optional>
|
||||
@ -11,6 +9,9 @@
|
||||
#include <filesystem>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
@ -25,7 +26,7 @@ namespace
|
||||
/// Based on the code of musl-libc and the answer of Kanalpiroge on
|
||||
/// https://stackoverflow.com/questions/15779185/list-all-the-functions-symbols-on-the-fly-in-c-code-on-a-linux-architecture
|
||||
void collectSymbolsFromProgramHeaders(dl_phdr_info * info,
|
||||
std::vector<DB::SymbolIndex::Symbol> & symbols)
|
||||
std::vector<SymbolIndex::Symbol> & symbols)
|
||||
{
|
||||
/* Iterate over all headers of the current shared lib
|
||||
* (first call is for the executable itself) */
|
||||
@ -129,13 +130,10 @@ void collectSymbolsFromProgramHeaders(dl_phdr_info * info,
|
||||
if (!sym_name)
|
||||
continue;
|
||||
|
||||
DB::SymbolIndex::Symbol symbol;
|
||||
SymbolIndex::Symbol symbol;
|
||||
symbol.address_begin = reinterpret_cast<const void *>(info->dlpi_addr + elf_sym[sym_index].st_value);
|
||||
symbol.address_end = reinterpret_cast<const void *>(info->dlpi_addr + elf_sym[sym_index].st_value + elf_sym[sym_index].st_size);
|
||||
int unused = 0;
|
||||
symbol.name = demangle(sym_name, unused);
|
||||
symbol.object = info->dlpi_name;
|
||||
|
||||
symbol.name = sym_name;
|
||||
symbols.push_back(std::move(symbol));
|
||||
}
|
||||
|
||||
@ -148,10 +146,10 @@ void collectSymbolsFromProgramHeaders(dl_phdr_info * info,
|
||||
|
||||
void collectSymbolsFromELFSymbolTable(
|
||||
dl_phdr_info * info,
|
||||
const DB::Elf & elf,
|
||||
const DB::Elf::Section & symbol_table,
|
||||
const DB::Elf::Section & string_table,
|
||||
std::vector<DB::SymbolIndex::Symbol> & symbols)
|
||||
const Elf & elf,
|
||||
const Elf::Section & symbol_table,
|
||||
const Elf::Section & string_table,
|
||||
std::vector<SymbolIndex::Symbol> & symbols)
|
||||
{
|
||||
/// Iterate symbol table.
|
||||
const ElfSym * symbol_table_entry = reinterpret_cast<const ElfSym *>(symbol_table.begin());
|
||||
@ -170,13 +168,13 @@ void collectSymbolsFromELFSymbolTable(
|
||||
/// Find the name in strings table.
|
||||
const char * symbol_name = strings + symbol_table_entry->st_name;
|
||||
|
||||
DB::SymbolIndex::Symbol symbol;
|
||||
if (!symbol_name)
|
||||
continue;
|
||||
|
||||
SymbolIndex::Symbol symbol;
|
||||
symbol.address_begin = reinterpret_cast<const void *>(info->dlpi_addr + symbol_table_entry->st_value);
|
||||
symbol.address_end = reinterpret_cast<const void *>(info->dlpi_addr + symbol_table_entry->st_value + symbol_table_entry->st_size);
|
||||
int unused = 0;
|
||||
symbol.name = demangle(symbol_name, unused);
|
||||
symbol.object = info->dlpi_name;
|
||||
|
||||
symbol.name = symbol_name;
|
||||
symbols.push_back(std::move(symbol));
|
||||
}
|
||||
}
|
||||
@ -184,15 +182,15 @@ void collectSymbolsFromELFSymbolTable(
|
||||
|
||||
bool searchAndCollectSymbolsFromELFSymbolTable(
|
||||
dl_phdr_info * info,
|
||||
const DB::Elf & elf,
|
||||
const Elf & elf,
|
||||
unsigned section_header_type,
|
||||
const char * string_table_name,
|
||||
std::vector<DB::SymbolIndex::Symbol> & symbols)
|
||||
std::vector<SymbolIndex::Symbol> & symbols)
|
||||
{
|
||||
std::optional<DB::Elf::Section> symbol_table;
|
||||
std::optional<DB::Elf::Section> string_table;
|
||||
std::optional<Elf::Section> symbol_table;
|
||||
std::optional<Elf::Section> string_table;
|
||||
|
||||
if (!elf.iterateSections([&](const DB::Elf::Section & section, size_t)
|
||||
if (!elf.iterateSections([&](const Elf::Section & section, size_t)
|
||||
{
|
||||
if (section.header.sh_type == section_header_type)
|
||||
symbol_table.emplace(section);
|
||||
@ -213,8 +211,8 @@ bool searchAndCollectSymbolsFromELFSymbolTable(
|
||||
|
||||
|
||||
void collectSymbolsFromELF(dl_phdr_info * info,
|
||||
std::vector<DB::SymbolIndex::Symbol> & symbols,
|
||||
std::vector<DB::SymbolIndex::Object> & objects)
|
||||
std::vector<SymbolIndex::Symbol> & symbols,
|
||||
std::vector<SymbolIndex::Object> & objects)
|
||||
{
|
||||
std::string object_name = info->dlpi_name;
|
||||
|
||||
@ -230,16 +228,17 @@ void collectSymbolsFromELF(dl_phdr_info * info,
|
||||
if (ec)
|
||||
return;
|
||||
|
||||
DB::Elf elf(object_name);
|
||||
|
||||
DB::SymbolIndex::Object object;
|
||||
SymbolIndex::Object object;
|
||||
object.elf = std::make_unique<Elf>(object_name);
|
||||
object.address_begin = reinterpret_cast<const void *>(info->dlpi_addr);
|
||||
object.address_end = reinterpret_cast<const void *>(info->dlpi_addr + elf.size());
|
||||
object.address_end = reinterpret_cast<const void *>(info->dlpi_addr + object.elf->size());
|
||||
object.name = object_name;
|
||||
objects.push_back(std::move(object));
|
||||
|
||||
searchAndCollectSymbolsFromELFSymbolTable(info, elf, SHT_SYMTAB, ".strtab", symbols);
|
||||
searchAndCollectSymbolsFromELFSymbolTable(info, elf, SHT_DYNSYM, ".dynstr", symbols);
|
||||
searchAndCollectSymbolsFromELFSymbolTable(info, *objects.back().elf, SHT_SYMTAB, ".strtab", symbols);
|
||||
|
||||
/// Unneeded because they were parsed from "program headers" of loaded objects.
|
||||
//searchAndCollectSymbolsFromELFSymbolTable(info, *objects.back().elf, SHT_DYNSYM, ".dynstr", symbols);
|
||||
}
|
||||
|
||||
|
||||
@ -253,7 +252,7 @@ int collectSymbols(dl_phdr_info * info, size_t, void * data_ptr)
|
||||
* (e.g. on a 32 bit system, ElfW(Dyn*) becomes "Elf32_Dyn*")
|
||||
*/
|
||||
|
||||
DB::SymbolIndex::Data & data = *reinterpret_cast<DB::SymbolIndex::Data *>(data_ptr);
|
||||
SymbolIndex::Data & data = *reinterpret_cast<SymbolIndex::Data *>(data_ptr);
|
||||
|
||||
collectSymbolsFromProgramHeaders(info, data.symbols);
|
||||
collectSymbolsFromELF(info, data.symbols, data.objects);
|
||||
@ -285,9 +284,6 @@ const T * find(const void * address, const std::vector<T> & vec)
|
||||
}
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
void SymbolIndex::update()
|
||||
{
|
||||
dl_iterate_phdr(collectSymbols, &data.symbols);
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <ext/singleton.h>
|
||||
#include <Common/Elf.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -9,16 +11,20 @@ namespace DB
|
||||
|
||||
/** Allow to quickly find symbol name from address.
|
||||
* Used as a replacement for "dladdr" function which is extremely slow.
|
||||
* It works better than "dladdr" because it also allows to search private symbols, that are not participated in shared linking.
|
||||
*/
|
||||
class SymbolIndex
|
||||
class SymbolIndex : public ext::singleton<SymbolIndex>
|
||||
{
|
||||
protected:
|
||||
friend class ext::singleton<SymbolIndex>;
|
||||
SymbolIndex() { update(); }
|
||||
|
||||
public:
|
||||
struct Symbol
|
||||
{
|
||||
const void * address_begin;
|
||||
const void * address_end;
|
||||
const char * object;
|
||||
std::string name; /// demangled NOTE Can use Arena for strings
|
||||
const char * name;
|
||||
};
|
||||
|
||||
struct Object
|
||||
@ -26,11 +32,9 @@ public:
|
||||
const void * address_begin;
|
||||
const void * address_end;
|
||||
std::string name;
|
||||
std::unique_ptr<Elf> elf;
|
||||
};
|
||||
|
||||
SymbolIndex() { update(); }
|
||||
void update();
|
||||
|
||||
const Symbol * findSymbol(const void * address) const;
|
||||
const Object * findObject(const void * address) const;
|
||||
|
||||
@ -44,6 +48,8 @@ public:
|
||||
};
|
||||
private:
|
||||
Data data;
|
||||
|
||||
void update();
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <Core/Field.h>
|
||||
#include <Poco/Logger.h>
|
||||
#include <common/Pipe.h>
|
||||
#include <common/StackTrace.h>
|
||||
#include <Common/StackTrace.h>
|
||||
#include <common/logger_useful.h>
|
||||
#include <IO/ReadHelpers.h>
|
||||
#include <IO/ReadBufferFromFileDescriptor.h>
|
||||
|
@ -18,9 +18,9 @@ int main(int argc, char ** argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
SymbolIndex symbol_index;
|
||||
const SymbolIndex & symbol_index = SymbolIndex::instance();
|
||||
|
||||
for (const auto & elem : symbol_index.objects())
|
||||
for (const auto & elem : symbol_index.symbols())
|
||||
std::cout << elem.name << ": " << elem.address_begin << " ... " << elem.address_end << "\n";
|
||||
|
||||
const void * address = reinterpret_cast<void*>(std::stoull(argv[1], nullptr, 16));
|
||||
@ -41,10 +41,12 @@ int main(int argc, char ** argv)
|
||||
Dwarf dwarf(elf);
|
||||
|
||||
Dwarf::LocationInfo location;
|
||||
if (dwarf.findAddress(uintptr_t(address), location, Dwarf::LocationInfoMode::FULL))
|
||||
if (dwarf.findAddress(uintptr_t(address), location, Dwarf::LocationInfoMode::FAST))
|
||||
std::cerr << location.file.toString() << ":" << location.line << "\n";
|
||||
else
|
||||
std::cerr << "Dwarf: Not found\n";
|
||||
|
||||
std::cerr << StackTrace().toString() << "\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ void registerFunctionsIntrospection(FunctionFactory &);
|
||||
void registerFunctionsNull(FunctionFactory &);
|
||||
void registerFunctionsFindCluster(FunctionFactory &);
|
||||
void registerFunctionsJSON(FunctionFactory &);
|
||||
void registerFunctionSymbolizeAddress(FunctionFactory &);
|
||||
void registerFunctionsIntrospection(FunctionFactory &);
|
||||
|
||||
void registerFunctions()
|
||||
{
|
||||
@ -79,7 +79,7 @@ void registerFunctions()
|
||||
registerFunctionsNull(factory);
|
||||
registerFunctionsFindCluster(factory);
|
||||
registerFunctionsJSON(factory);
|
||||
registerFunctionSymbolizeAddress(factory);
|
||||
registerFunctionsIntrospection(factory);
|
||||
}
|
||||
|
||||
}
|
||||
|
16
dbms/src/Functions/registerFunctionsIntrospection.cpp
Normal file
16
dbms/src/Functions/registerFunctionsIntrospection.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
namespace DB
|
||||
{
|
||||
|
||||
class FunctionFactory;
|
||||
|
||||
void registerFunctionSymbolizeAddress(FunctionFactory & factory);
|
||||
void registerFunctionDemangle(FunctionFactory & factory);
|
||||
|
||||
void registerFunctionsIntrospection(FunctionFactory & factory)
|
||||
{
|
||||
registerFunctionSymbolizeAddress(factory);
|
||||
registerFunctionDemangle(factory);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
extern const int SIZES_OF_ARRAYS_DOESNT_MATCH;
|
||||
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
||||
}
|
||||
|
||||
@ -60,7 +59,7 @@ public:
|
||||
|
||||
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override
|
||||
{
|
||||
static SymbolIndex symbol_index;
|
||||
const SymbolIndex & symbol_index = SymbolIndex::instance();
|
||||
|
||||
const ColumnPtr & column = block.getByPosition(arguments[0]).column;
|
||||
const ColumnUInt64 * column_concrete = checkAndGetColumn<ColumnUInt64>(column.get());
|
||||
@ -74,7 +73,7 @@ public:
|
||||
for (size_t i = 0; i < input_rows_count; ++i)
|
||||
{
|
||||
if (const auto * symbol = symbol_index.findSymbol(reinterpret_cast<const void *>(data[i])))
|
||||
result_column->insertDataWithTerminatingZero(symbol->name.data(), symbol->name.size() + 1);
|
||||
result_column->insertDataWithTerminatingZero(symbol->name, strlen(symbol->name) + 1);
|
||||
else
|
||||
result_column->insertDefault();
|
||||
}
|
||||
|
@ -50,7 +50,7 @@
|
||||
#include <Parsers/ASTCreateQuery.h>
|
||||
#include <Parsers/ParserCreateQuery.h>
|
||||
#include <Parsers/parseQuery.h>
|
||||
#include <common/StackTrace.h>
|
||||
#include <Common/StackTrace.h>
|
||||
#include <Common/Config/ConfigProcessor.h>
|
||||
#include <Common/ZooKeeper/ZooKeeper.h>
|
||||
#include <Common/ShellCommand.h>
|
||||
|
@ -23,12 +23,10 @@ add_library (common
|
||||
src/getThreadNumber.cpp
|
||||
src/sleep.cpp
|
||||
src/argsToConfig.cpp
|
||||
src/StackTrace.cpp
|
||||
src/Pipe.cpp
|
||||
src/phdr_cache.cpp
|
||||
|
||||
include/common/SimpleCache.h
|
||||
include/common/StackTrace.h
|
||||
include/common/Types.h
|
||||
include/common/DayNum.h
|
||||
include/common/DateLUT.h
|
||||
@ -68,14 +66,6 @@ add_library (common
|
||||
|
||||
${CONFIG_COMMON})
|
||||
|
||||
if (USE_UNWIND)
|
||||
target_compile_definitions (common PRIVATE USE_UNWIND=1)
|
||||
target_include_directories (common BEFORE PRIVATE ${UNWIND_INCLUDE_DIR})
|
||||
if (NOT USE_INTERNAL_UNWIND_LIBRARY_FOR_EXCEPTION_HANDLING)
|
||||
target_link_libraries (common PRIVATE ${UNWIND_LIBRARY})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# When testing for memory leaks with Valgrind, dont link tcmalloc or jemalloc.
|
||||
|
||||
if (USE_JEMALLOC)
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <common/logger_useful.h>
|
||||
#include <common/ErrorHandlers.h>
|
||||
#include <common/Pipe.h>
|
||||
#include <common/StackTrace.h>
|
||||
#include <Common/StackTrace.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <iostream>
|
||||
|
Loading…
Reference in New Issue
Block a user