look for symbols in dynsym table (#990)
* look for symbols in dynsym table
* checking both symtab and dynsym
* Avoid symbol duplication in non stripped binaries
* clang-format
* Minor elf_utils.cpp updates
- use 'else if' instead of 'if'
- logging tweaks
* Update registration
- tweak logging
* Update testing
- strip the rocprofiler-sdk-c-tool library
- add test-c-tool-rocp-tool-lib-execute test which does NOT LD_PRELOAD the library (uses only ROCP_TOOL_LIBRARIES instead)
---------
Co-authored-by: Jonathan R. Madsen <jonathanrmadsen@gmail.com>
[ROCm/rocprofiler-sdk commit: dc671497da]
This commit is contained in:
zatwierdzone przez
GitHub
rodzic
185094eee1
commit
2393b2ee45
@@ -89,6 +89,11 @@ ElfInfo::has_symbol(std::regex&& _re) const
|
||||
{
|
||||
if(!itr.name.empty() && std::regex_search(itr.name, _re)) return true;
|
||||
}
|
||||
// For stripped binaries
|
||||
for(const auto& itr : dynamic_symbol_entries)
|
||||
{
|
||||
if(!itr.name.empty() && std::regex_search(itr.name, _re)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -96,12 +101,13 @@ ElfInfo::has_symbol(std::regex&& _re) const
|
||||
ElfInfo
|
||||
read(const std::string& _inp)
|
||||
{
|
||||
auto _info = ElfInfo{_inp};
|
||||
auto& reader = _info.reader;
|
||||
auto& sections = _info.sections;
|
||||
auto& symbol_entries = _info.symbol_entries;
|
||||
auto& dynamic_entries = _info.dynamic_entries;
|
||||
auto& reloc_entries = _info.reloc_entries;
|
||||
auto _info = ElfInfo{_inp};
|
||||
auto& reader = _info.reader;
|
||||
auto& sections = _info.sections;
|
||||
auto& symbol_entries = _info.symbol_entries;
|
||||
auto& dynamic_symbol_entries = _info.dynamic_symbol_entries;
|
||||
auto& dynamic_entries = _info.dynamic_entries;
|
||||
auto& reloc_entries = _info.reloc_entries;
|
||||
|
||||
ROCP_TRACE << "\nReading " << _inp;
|
||||
|
||||
@@ -148,10 +154,17 @@ read(const std::string& _inp)
|
||||
if(psec->get_type() == ELFIO::SHT_SYMTAB)
|
||||
{
|
||||
const ELFIO::symbol_section_accessor _symbols(reader, psec);
|
||||
ROCP_TRACE << " Number of symbol_entries: " << _symbols.get_symbols_num();
|
||||
ROCP_TRACE << " Number of symbol entries: " << _symbols.get_symbols_num();
|
||||
for(ELFIO::Elf_Xword k = 0; k < _symbols.get_symbols_num(); ++k)
|
||||
symbol_entries.emplace_back(k, _symbols);
|
||||
}
|
||||
else if(psec->get_type() == ELFIO::SHT_DYNSYM)
|
||||
{
|
||||
const ELFIO::symbol_section_accessor _symbols(reader, psec);
|
||||
ROCP_TRACE << " Number of dynamic symbol entries: " << _symbols.get_symbols_num();
|
||||
for(ELFIO::Elf_Xword k = 0; k < _symbols.get_symbols_num(); ++k)
|
||||
dynamic_symbol_entries.emplace_back(k, _symbols);
|
||||
}
|
||||
else if(psec->get_type() == ELFIO::SHT_DYNAMIC)
|
||||
{
|
||||
const ELFIO::dynamic_section_accessor dynamic{reader, psec};
|
||||
@@ -175,6 +188,13 @@ read(const std::string& _inp)
|
||||
ROCP_TRACE << " [" << k << "] " << symbol_entries.at(k).name;
|
||||
}
|
||||
|
||||
ROCP_TRACE << "Dynamic Symbols:";
|
||||
for(size_t k = 0; k < dynamic_symbol_entries.size(); ++k)
|
||||
{
|
||||
if(!dynamic_symbol_entries.at(k).name.empty())
|
||||
ROCP_TRACE << " [" << k << "] " << dynamic_symbol_entries.at(k).name;
|
||||
}
|
||||
|
||||
ROCP_TRACE << "Dynamic entries:";
|
||||
for(size_t k = 0; k < dynamic_entries.size(); ++k)
|
||||
{
|
||||
|
||||
@@ -86,12 +86,13 @@ struct ElfInfo
|
||||
{
|
||||
explicit ElfInfo(std::string);
|
||||
|
||||
std::string filename = {};
|
||||
ELFIO::elfio reader = {};
|
||||
std::vector<Section*> sections = {};
|
||||
std::vector<SymbolEntry> symbol_entries = {};
|
||||
std::vector<DynamicEntry> dynamic_entries = {};
|
||||
std::vector<RelocationEntry> reloc_entries = {};
|
||||
std::string filename = {};
|
||||
ELFIO::elfio reader = {};
|
||||
std::vector<Section*> sections = {};
|
||||
std::vector<SymbolEntry> symbol_entries = {};
|
||||
std::vector<SymbolEntry> dynamic_symbol_entries = {};
|
||||
std::vector<DynamicEntry> dynamic_entries = {};
|
||||
std::vector<RelocationEntry> reloc_entries = {};
|
||||
|
||||
bool has_symbol(std::regex&&) const;
|
||||
|
||||
|
||||
@@ -246,15 +246,16 @@ find_clients()
|
||||
{
|
||||
for(const auto& itr : env)
|
||||
{
|
||||
ROCP_INFO << "[env] searching " << itr << " for rocprofiler_configure";
|
||||
ROCP_INFO << "[ROCP_TOOL_LIBRARIES] searching " << itr << " for rocprofiler_configure";
|
||||
|
||||
if(fs::exists(itr))
|
||||
{
|
||||
auto elfinfo = common::elf_utils::read(itr);
|
||||
if(!elfinfo.has_symbol(std::regex{"^rocprofiler_configure$"}))
|
||||
{
|
||||
ROCP_FATAL << "rocprofiler tool library " << itr
|
||||
<< " did not contain rocprofiler_configure symbol";
|
||||
ROCP_FATAL << "[ROCP_TOOL_LIBRARIES] rocprofiler-sdk tool library '" << itr
|
||||
<< "' did not contain rocprofiler_configure symbol (search method: "
|
||||
"ELF parsing)";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,15 +263,14 @@ find_clients()
|
||||
|
||||
if(!handle)
|
||||
{
|
||||
ROCP_WARNING << "[env] " << itr
|
||||
<< " is not already loaded, doing a local lazy dlopen...";
|
||||
ROCP_INFO << "[ROCP_TOOL_LIBRARIES] '" << itr
|
||||
<< "' is not already loaded, doing a local lazy dlopen...";
|
||||
handle = dlopen(itr.c_str(), RTLD_LOCAL | RTLD_LAZY);
|
||||
}
|
||||
|
||||
if(!handle)
|
||||
{
|
||||
ROCP_ERROR << "error dlopening " << itr;
|
||||
continue;
|
||||
ROCP_FATAL << "[ROCP_TOOL_LIBRARIES] error dlopening '" << itr << "'";
|
||||
}
|
||||
|
||||
for(const auto& ditr : data)
|
||||
@@ -286,8 +286,9 @@ find_clients()
|
||||
{
|
||||
auto _sym = rocprofiler_configure_dlsym(handle);
|
||||
// FATAL bc they explicitly said this was a tool library
|
||||
ROCP_FATAL_IF(!_sym) << "rocprofiler tool library " << itr
|
||||
<< " did not contain rocprofiler_configure symbol";
|
||||
ROCP_FATAL_IF(!_sym)
|
||||
<< "[ROCP_TOOL_LIBRARIES] rocprofiler-sdk tool library '" << itr
|
||||
<< "' did not contain rocprofiler_configure symbol (search method: dlsym)";
|
||||
if(is_unique_configure_func(_sym)) emplace_client(itr, handle, _sym);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,3 +37,26 @@ set_tests_properties(
|
||||
"Test C tool \\(priority=0\\) is using rocprofiler-sdk v([0-9]+\\.[0-9]+\\.[0-9]+)"
|
||||
FAIL_REGULAR_EXPRESSION
|
||||
"${ROCPROFILER_DEFAULT_FAIL_REGEX}")
|
||||
|
||||
# this test uses ROCP_TOOL_LIBRARIES instead of LD_PRELOAD
|
||||
add_test(NAME test-c-tool-rocp-tool-lib-execute COMMAND $<TARGET_FILE:transpose> 1)
|
||||
|
||||
set(c-tool-rocp-tool-lib-env
|
||||
"${ROCPROFILER_MEMCHECK_PRELOAD_ENV}"
|
||||
"ROCP_TOOL_LIBRARIES=$<TARGET_FILE:rocprofiler-sdk-c-tool>"
|
||||
"LD_LIBRARY_PATH=$<TARGET_FILE_DIR:rocprofiler-sdk::rocprofiler-shared-library>:$ENV{LD_LIBRARY_PATH}"
|
||||
)
|
||||
|
||||
set_tests_properties(
|
||||
test-c-tool-rocp-tool-lib-execute
|
||||
PROPERTIES
|
||||
TIMEOUT
|
||||
45
|
||||
LABELS
|
||||
"integration-tests"
|
||||
ENVIRONMENT
|
||||
"${c-tool-rocp-tool-lib-env}"
|
||||
PASS_REGULAR_EXPRESSION
|
||||
"Test C tool \\(priority=0\\) is using rocprofiler-sdk v([0-9]+\\.[0-9]+\\.[0-9]+)"
|
||||
FAIL_REGULAR_EXPRESSION
|
||||
"${ROCPROFILER_DEFAULT_FAIL_REGEX}")
|
||||
|
||||
@@ -38,3 +38,14 @@ set_target_properties(
|
||||
VERSION
|
||||
${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}
|
||||
INSTALL_RPATH "\$ORIGIN:\$ORIGIN/..")
|
||||
|
||||
if(NOT CMAKE_STRIP)
|
||||
find_program(CMAKE_STRIP NAMES strip REQUIRED)
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
TARGET rocprofiler-sdk-c-tool
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_STRIP} $<TARGET_FILE:rocprofiler-sdk-c-tool>
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "Stripping rocprofiler-sdk-c-tool...")
|
||||
|
||||
Reference in New Issue
Block a user