fix omnitrace print-* with libraries (#94)

* fix omnitrace print-* with libraries

* timemory submodule update

* Update workflows to use ./bin/omnitrace instead of ./omnitrace

* cmake format

* update timemory submodule

- fix ODR violations in utility/procfs

* cmake updates

- uniform find_package for all ROCm-based libraries

* tweak transpose example

- throw exception instead of std::exit

* Inspect cmdv name before assuming not exe

- some ELF execs "think" they are libraries so only assume rewrite + simulate + all-functions if filename looks like library
- adds some test for --print-available -- <library>

* Fix _has_lib_prefix when command is < 3

* Updates and reverts to omnitrace exe

- update module_function operator< and operator==
- add function_signature operator<
- refactor module_function ctor
- revert some previous changes w.r.t. simulate and include_unninstr

* Fix source/bin/tests to use same output dir as tests

* cmake format

* Segfault mitigation + refactor + modify function iteration

- refactor module_function ctor to avoid segfaults
- string_t -> std::string
- replace std::string with std::string_view in some places
- get_name(module_t*)
- get_name(procedure_t*)
- disable using both app_modules and app_functions
- new option: --parse-all-modules to iterate over app_modules
- removed some unused code w.r.t. debug info

* Disable module_function address range for uninstrumentable functions

* Disable module_function address range for uninstrumentable functions

* Refactored getting file/line info and init/fini

- use dyninst insertInitCallback and insertFiniCallback if main not found
- fixed all issues with segmentation faults in --simulate --all-functions

* revert changes to Findrocprofiler.cmake
Этот коммит содержится в:
Jonathan R. Madsen
2022-07-21 01:15:41 -05:00
коммит произвёл GitHub
родитель 6bc86d1111
Коммит d04cbe862e
29 изменённых файлов: 781 добавлений и 531 удалений
+1
Просмотреть файл
@@ -51,6 +51,7 @@ parse:
omnitrace_add_bin_test:
flags:
- WILL_FAIL
- ADD_INVERSE
kwargs:
NAME: '*'
ARGS: '*'
+2 -2
Просмотреть файл
@@ -73,8 +73,8 @@ jobs:
timeout-minutes: 45
run:
cd build &&
ldd ./omnitrace &&
./omnitrace --help &&
ldd ./bin/omnitrace &&
./bin/omnitrace --help &&
ctest -V -N -O omnitrace-ctest-${{ github.job }}-commands.log &&
ctest -V --output-log omnitrace-ctest-${{ github.job }}.log --stop-on-failure
+2 -2
Просмотреть файл
@@ -102,8 +102,8 @@ jobs:
timeout-minutes: 45
run:
cd build &&
ldd ./omnitrace &&
./omnitrace --help &&
ldd ./bin/omnitrace &&
./bin/omnitrace --help &&
ctest -V -N -O omnitrace-ctest-${{ github.job }}-commands.log &&
ctest -V --output-log omnitrace-ctest-${{ github.job }}.log --stop-on-failure
+4 -4
Просмотреть файл
@@ -118,8 +118,8 @@ jobs:
timeout-minutes: 45
run:
cd build &&
ldd ./omnitrace &&
./omnitrace --help &&
ldd ./bin/omnitrace &&
./bin/omnitrace --help &&
ctest -V -N -O omnitrace-ctest-${{ github.job }}-commands.log &&
ctest -V --output-log omnitrace-ctest-${{ github.job }}.log --stop-on-failure
@@ -241,8 +241,8 @@ jobs:
timeout-minutes: 45
run:
cd build &&
ldd ./omnitrace &&
./omnitrace --help &&
ldd ./bin/omnitrace &&
./bin/omnitrace --help &&
ctest -V -N -O omnitrace-ctest-${{ github.job }}-commands.log &&
ctest -V --output-log omnitrace-ctest-${{ github.job }}.log --stop-on-failure
+36 -27
Просмотреть файл
@@ -781,6 +781,39 @@ function(OMNITRACE_FIND_SHARED_LIBRARY)
find_library(${ARGN})
endfunction()
function(OMNITRACE_BUILDTREE_TPL _TPL_TARGET _NEW_NAME _BUILD_TREE_DIR)
get_target_property(_TPL_VERSION ${_TPL_TARGET} VERSION)
get_target_property(_TPL_SOVERSION ${_TPL_TARGET} SOVERSION)
get_target_property(_TPL_NAME ${_TPL_TARGET} OUTPUT_NAME)
set(_TPL_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX})
set(_TPL_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
foreach(_TAIL ${_TPL_SUFFIX} ${_TPL_SUFFIX}.${_TPL_SOVERSION}
${_TPL_SUFFIX}.${_TPL_VERSION})
set(_INP ${_TPL_PREFIX}${_TPL_NAME}${_TAIL})
set(_OUT ${_TPL_PREFIX}${_NEW_NAME}${_TAIL})
endforeach()
string(REPLACE " " "-" _TAIL "${ARGN}")
# build tree symbolic links
add_custom_target(
${_NEW_NAME}-build-tree-library${_TAIL} ALL
${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${_TPL_TARGET}>
${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION}
COMMAND
${CMAKE_COMMAND} -E create_symlink
${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION}
${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION}
COMMAND
${CMAKE_COMMAND} -E create_symlink
${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION}
${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}
WORKING_DIRECTORY ${_BUILD_TREE_DIR}
DEPENDS ${_TPL_TARGET}
COMMENT "Creating ${_NEW_NAME} from ${_TPL_TARGET}...")
endfunction()
function(OMNITRACE_INSTALL_TPL _TPL_TARGET _NEW_NAME _BUILD_TREE_DIR)
get_target_property(_TPL_VERSION ${_TPL_TARGET} VERSION)
get_target_property(_TPL_SOVERSION ${_TPL_TARGET} SOVERSION)
@@ -795,41 +828,17 @@ function(OMNITRACE_INSTALL_TPL _TPL_TARGET _NEW_NAME _BUILD_TREE_DIR)
endforeach()
# build tree symbolic links
add_custom_target(
${_NEW_NAME}-library ALL
${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${_TPL_TARGET}>
${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION}
COMMAND
${CMAKE_COMMAND} -E create_symlink
${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION}
${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION}
COMMAND
${CMAKE_COMMAND} -E create_symlink
${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION}
${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}
WORKING_DIRECTORY ${_BUILD_TREE_DIR}
DEPENDS ${_TPL_TARGET}
COMMENT "Creating ${_NEW_NAME} from ${_TPL_TARGET}...")
omnitrace_buildtree_tpl("${_TPL_TARGET}" "${_NEW_NAME}" "${_BUILD_TREE_DIR}" ${ARGN})
install(
FILES $<TARGET_FILE:${_TPL_TARGET}>
DESTINATION ${CMAKE_INSTALL_LIBDIR}
RENAME ${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION})
execute_process(
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/install-tree
COMMAND
${CMAKE_COMMAND} -E create_symlink
${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION}
${PROJECT_BINARY_DIR}/install-tree/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION}
COMMAND
${CMAKE_COMMAND} -E create_symlink
${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION}
${PROJECT_BINARY_DIR}/install-tree/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX})
install(
FILES
${PROJECT_BINARY_DIR}/install-tree/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION}
${PROJECT_BINARY_DIR}/install-tree/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}
${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION}
${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}
DESTINATION ${CMAKE_INSTALL_LIBDIR})
endfunction()
+10 -4
Просмотреть файл
@@ -217,10 +217,13 @@ function(ROCM_VERSION_PARSE_VERSION_FILES)
endif()
# convert env to cache if not defined
foreach(_PATH ROCmVersion_DIR ROCmVersion_ROOT ROCmVersion_ROOT_DIR ROCM_PATH)
foreach(_PATH ROCmVersion_DIR ROCmVersion_ROOT ROCmVersion_ROOT_DIR
OMNITRACE_DEFAULT_ROCM_PATH ROCM_PATH)
if(NOT DEFINED ${_PATH} AND DEFINED ENV{${_PATH}})
set(_VAL "$ENV{${_PATH}}")
get_filename_component(_VAL "${_VAL}" REALPATH)
set(${_PATH}
"$ENV{${_PATH}}"
"${_VAL}"
CACHE PATH "Search path for ROCm version for ROCmVersion")
endif()
endforeach()
@@ -229,8 +232,11 @@ function(ROCM_VERSION_PARSE_VERSION_FILES)
set(_PATHS ${ROCmVersion_DIR})
else()
set(_PATHS)
foreach(_DIR ${ROCmVersion_DIR} ${ROCmVersion_ROOT} ${ROCmVersion_ROOT_DIR}
$ENV{CMAKE_PREFIX_PATH} ${CMAKE_PREFIX_PATH} ${ROCM_PATH} /opt/rocm)
foreach(
_DIR
${ROCmVersion_DIR} ${ROCmVersion_ROOT} ${ROCmVersion_ROOT_DIR}
$ENV{CMAKE_PREFIX_PATH} ${CMAKE_PREFIX_PATH} ${OMNITRACE_DEFAULT_ROCM_PATH}
${ROCM_PATH} /opt/rocm)
if(EXISTS ${_DIR})
get_filename_component(_ABS_DIR "${_DIR}" REALPATH)
list(APPEND _PATHS ${_ABS_DIR})
+1 -1
Просмотреть файл
@@ -9,7 +9,7 @@ if(NOT ROCM_PATH AND NOT "$ENV{ROCM_PATH}" STREQUAL "")
set(ROCM_PATH "$ENV{ROCM_PATH}")
endif()
foreach(_DIR ${ROCM_PATH} /opt/rocm /opt/rocm/rocm_smi)
foreach(_DIR ${ROCmVersion_DIR} ${ROCM_PATH} /opt/rocm /opt/rocm/rocm_smi)
if(EXISTS ${_DIR})
get_filename_component(_ABS_DIR "${_DIR}" REALPATH)
list(APPEND _ROCM_SMI_PATHS ${_ABS_DIR})
+1 -2
Просмотреть файл
@@ -9,7 +9,7 @@ if(NOT ROCM_PATH AND NOT "$ENV{ROCM_PATH}" STREQUAL "")
set(ROCM_PATH "$ENV{ROCM_PATH}")
endif()
foreach(_DIR ${ROCM_PATH} /opt/rocm /opt/rocm/rocprofiler)
foreach(_DIR ${ROCmVersion_DIR} ${ROCM_PATH} /opt/rocm /opt/rocm/rocprofiler)
if(EXISTS ${_DIR})
get_filename_component(_ABS_DIR "${_DIR}" REALPATH)
list(APPEND _ROCM_ROCPROFILER_PATHS ${_ABS_DIR})
@@ -48,7 +48,6 @@ find_path(
mark_as_advanced(rocprofiler_hsa_INCLUDE_DIR)
# ----------------------------------------------------------------------------------------#
find_library(
rocprofiler_LIBRARY
NAMES rocprofiler64 rocprofiler
+3 -2
Просмотреть файл
@@ -9,7 +9,7 @@ if(NOT ROCM_PATH AND NOT "$ENV{ROCM_PATH}" STREQUAL "")
set(ROCM_PATH "$ENV{ROCM_PATH}")
endif()
foreach(_DIR ${ROCM_PATH} /opt/rocm /opt/rocm/roctracer)
foreach(_DIR ${ROCmVersion_DIR} ${ROCM_PATH} /opt/rocm /opt/rocm/roctracer)
if(EXISTS ${_DIR})
get_filename_component(_ABS_DIR "${_DIR}" REALPATH)
list(APPEND _ROCM_ROCTRACER_PATHS ${_ABS_DIR})
@@ -70,7 +70,8 @@ find_library(
PATHS ${roctracer_ROOT_DIR} ${_ROCM_ROCTRACER_PATHS}
PATH_SUFFIXES lib lib64)
find_package(hsakmt)
find_package(hsakmt HINTS ${_ROCM_ROCTRACER_PATHS} PATHS ${_ROCM_ROCTRACER_PATHS})
if(hsakmt_FOUND)
set(roctracer_hsakmt_LIBRARY
hsakmt::hsakmt
+52 -36
Просмотреть файл
@@ -57,8 +57,14 @@ set(OMNITRACE_DEFAULT_ROCM_PATH
/opt/rocm
CACHE PATH "Default search path for ROCM")
if(EXISTS ${OMNITRACE_DEFAULT_ROCM_PATH})
get_filename_component(OMNITRACE_DEFAULT_ROCM_PATH "${OMNITRACE_DEFAULT_ROCM_PATH}"
get_filename_component(_OMNITRACE_DEFAULT_ROCM_PATH "${OMNITRACE_DEFAULT_ROCM_PATH}"
REALPATH)
if(NOT "${_OMNITRACE_DEFAULT_ROCM_PATH}" STREQUAL "${OMNITRACE_DEFAULT_ROCM_PATH}")
set(OMNITRACE_DEFAULT_ROCM_PATH
"${_OMNITRACE_DEFAULT_ROCM_PATH}"
CACHE PATH "Default search path for ROCM" FORCE)
endif()
endif()
# ----------------------------------------------------------------------------------------#
@@ -93,6 +99,49 @@ foreach(_LIB dl rt)
endif()
endforeach()
# ----------------------------------------------------------------------------------------#
#
# hip version
#
# ----------------------------------------------------------------------------------------#
if(OMNITRACE_USE_HIP
OR OMNITRACE_USE_ROCTRACER
OR OMNITRACE_USE_ROCPROFILER
OR OMNITRACE_USE_ROCM_SMI)
find_package(ROCmVersion)
if(NOT ROCmVersion_FOUND)
find_package(hip ${omnitrace_FIND_QUIETLY} REQUIRED HINTS
${OMNITRACE_DEFAULT_ROCM_PATH} PATHS ${OMNITRACE_DEFAULT_ROCM_PATH})
find_package(ROCmVersion REQUIRED HINTS ${ROCM_PATH} PATHS ${ROCM_PATH})
endif()
list(APPEND CMAKE_PREFIX_PATH ${ROCmVersion_DIR})
set(OMNITRACE_ROCM_VERSION ${ROCmVersion_FULL_VERSION})
set(OMNITRACE_HIP_VERSION_MAJOR ${ROCmVersion_MAJOR_VERSION})
set(OMNITRACE_HIP_VERSION_MINOR ${ROCmVersion_MINOR_VERSION})
set(OMNITRACE_HIP_VERSION_PATCH ${ROCmVersion_PATCH_VERSION})
set(OMNITRACE_HIP_VERSION ${ROCmVersion_TRIPLE_VERSION})
if(OMNITRACE_HIP_VERSION_MAJOR GREATER_EQUAL 4 AND OMNITRACE_HIP_VERSION_MINOR
GREATER 3)
set(roctracer_kfdwrapper_LIBRARY)
endif()
if(NOT roctracer_kfdwrapper_LIBRARY)
set(roctracer_kfdwrapper_LIBRARY)
endif()
omnitrace_add_feature(OMNITRACE_ROCM_VERSION "ROCm version used by omnitrace")
else()
set(OMNITRACE_HIP_VERSION "0.0.0")
set(OMNITRACE_HIP_VERSION_MAJOR 0)
set(OMNITRACE_HIP_VERSION_MINOR 0)
set(OMNITRACE_HIP_VERSION_PATCH 0)
endif()
# ----------------------------------------------------------------------------------------#
#
# HIP
@@ -100,7 +149,6 @@ endforeach()
# ----------------------------------------------------------------------------------------#
if(OMNITRACE_USE_HIP)
list(APPEND CMAKE_PREFIX_PATH ${OMNITRACE_DEFAULT_ROCM_PATH})
find_package(hip ${omnitrace_FIND_QUIETLY} REQUIRED)
omnitrace_target_compile_definitions(omnitrace-hip INTERFACE OMNITRACE_USE_HIP)
target_link_libraries(omnitrace-hip INTERFACE hip::host)
@@ -113,7 +161,6 @@ endif()
# ----------------------------------------------------------------------------------------#
if(OMNITRACE_USE_ROCTRACER)
list(APPEND CMAKE_PREFIX_PATH ${OMNITRACE_DEFAULT_ROCM_PATH})
find_package(roctracer ${omnitrace_FIND_QUIETLY} REQUIRED)
omnitrace_target_compile_definitions(omnitrace-roctracer
INTERFACE OMNITRACE_USE_ROCTRACER)
@@ -128,7 +175,6 @@ endif()
#
# ----------------------------------------------------------------------------------------#
if(OMNITRACE_USE_ROCPROFILER)
list(APPEND CMAKE_PREFIX_PATH ${OMNITRACE_DEFAULT_ROCM_PATH})
find_package(rocprofiler ${omnitrace_FIND_QUIETLY} REQUIRED)
omnitrace_target_compile_definitions(omnitrace-rocprofiler
INTERFACE OMNITRACE_USE_ROCPROFILER)
@@ -143,7 +189,6 @@ endif()
# ----------------------------------------------------------------------------------------#
if(OMNITRACE_USE_ROCM_SMI)
list(APPEND CMAKE_PREFIX_PATH ${OMNITRACE_DEFAULT_ROCM_PATH})
find_package(rocm-smi ${omnitrace_FIND_QUIETLY} REQUIRED)
omnitrace_target_compile_definitions(omnitrace-rocm-smi
INTERFACE OMNITRACE_USE_ROCM_SMI)
@@ -151,36 +196,6 @@ if(OMNITRACE_USE_ROCM_SMI)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}:${rocm-smi_LIBRARY_DIRS}")
endif()
# ----------------------------------------------------------------------------------------#
#
# hip version
#
# ----------------------------------------------------------------------------------------#
if(OMNITRACE_USE_HIP
OR OMNITRACE_USE_ROCTRACER
OR OMNITRACE_USE_ROCM_SMI)
find_package(ROCmVersion REQUIRED)
set(OMNITRACE_ROCM_VERSION ${ROCmVersion_FULL_VERSION})
set(OMNITRACE_HIP_VERSION_MAJOR ${ROCmVersion_MAJOR_VERSION})
set(OMNITRACE_HIP_VERSION_MINOR ${ROCmVersion_MINOR_VERSION})
set(OMNITRACE_HIP_VERSION_PATCH ${ROCmVersion_PATCH_VERSION})
set(OMNITRACE_HIP_VERSION ${ROCmVersion_TRIPLE_VERSION})
if(OMNITRACE_HIP_VERSION_MAJOR GREATER_EQUAL 4 AND OMNITRACE_HIP_VERSION_MINOR
GREATER 3)
set(roctracer_kfdwrapper_LIBRARY)
endif()
if(NOT roctracer_kfdwrapper_LIBRARY)
set(roctracer_kfdwrapper_LIBRARY)
endif()
omnitrace_add_feature(OMNITRACE_ROCM_VERSION "ROCm version used by omnitrace")
else()
set(OMNITRACE_HIP_VERSION "0.0.0")
set(OMNITRACE_HIP_VERSION_MAJOR 0)
set(OMNITRACE_HIP_VERSION_MINOR 0)
set(OMNITRACE_HIP_VERSION_PATCH 0)
endif()
# ----------------------------------------------------------------------------------------#
#
# MPI
@@ -276,7 +291,8 @@ if(OMNITRACE_BUILD_DYNINST)
endif()
endforeach()
omnitrace_install_tpl(dyninstAPI_RT omnitrace-rt "${PROJECT_BINARY_DIR}")
omnitrace_install_tpl(dyninstAPI_RT omnitrace-rt
"${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
# for packaging
install(
+2 -2
Просмотреть файл
@@ -12,8 +12,8 @@ option(BUILD_SHARED_LIBS "Build dynamic libraries" ON)
if(CMAKE_PROJECT_NAME STREQUAL "omnitrace")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
omnitrace_add_option(OMNITRACE_INSTALL_EXAMPLES "Install omnitrace examples" OFF)
else()
option(OMNITRACE_INSTALL_EXAMPLES "Install omnitrace examples" ON)
+3 -3
Просмотреть файл
@@ -13,13 +13,13 @@ if(LULESH_BUILD_KOKKOS)
kokkos_compilation(PROJECT)
elseif(LULESH_USE_HIP AND NOT "${CMAKE_CXX_COMPILER}" MATCHES "hipcc")
if(NOT HIPCC_EXECUTABLE)
find_package(hip QUIET)
find_package(hip QUIET HINTS ${ROCmVersion_DIR} PATHS ${ROCmVersion_DIR})
find_program(
HIPCC_EXECUTABLE
NAMES hipcc
HINTS ${ROCM_PATH} ENV ROCM_PATH /opt/rocm
PATHS ${ROCM_PATH} ENV ROCM_PATH /opt/rocm)
HINTS ${ROCmVersion_DIR} ${ROCM_PATH} ENV ROCM_PATH /opt/rocm
PATHS ${ROCmVersion_DIR} ${ROCM_PATH} ENV ROCM_PATH /opt/rocm)
mark_as_advanced(HIPCC_EXECUTABLE)
endif()
kokkos_compilation(PROJECT COMPILER ${HIPCC_EXECUTABLE})
+3 -3
Просмотреть файл
@@ -2,13 +2,13 @@ cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
project(omnitrace-transpose LANGUAGES CXX)
find_package(hip QUIET)
find_package(hip QUIET HINTS ${ROCmVersion_DIR} PATHS ${ROCmVersion_DIR})
find_program(
HIPCC_EXECUTABLE
NAMES hipcc
HINTS ${ROCM_PATH} ENV ROCM_PATH /opt/rocm
PATHS ${ROCM_PATH} ENV ROCM_PATH /opt/rocm)
HINTS ${ROCmVersion_DIR} ${ROCM_PATH} ENV ROCM_PATH /opt/rocm
PATHS ${ROCmVersion_DIR} ${ROCM_PATH} ENV ROCM_PATH /opt/rocm NO_CACHE)
mark_as_advanced(HIPCC_EXECUTABLE)
if(NOT HIPCC_EXECUTABLE)
+3 -2
Просмотреть файл
@@ -32,6 +32,7 @@ THE SOFTWARE.
#include <iostream>
#include <mutex>
#include <random>
#include <stdexcept>
#include <thread>
#include <vector>
@@ -46,7 +47,7 @@ using auto_lock_t = std::unique_lock<std::mutex>;
auto_lock_t _lk{ print_lock }; \
fprintf(stderr, "%s:%d :: HIP error : %s\n", __FILE__, __LINE__, \
hipGetErrorString(error_)); \
exit(EXIT_FAILURE); \
throw std::runtime_error("hip_api_call"); \
} \
}
@@ -58,7 +59,7 @@ check_hip_error(void)
{
auto_lock_t _lk{ print_lock };
std::cerr << "Error: " << hipGetErrorString(err) << std::endl;
exit(err);
throw std::runtime_error("hip_api_call");
}
}
поставляемый
+1 -1
+3 -3
Просмотреть файл
@@ -6,9 +6,9 @@ if(OMNITRACE_BUILD_LTO)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
endif()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
add_subdirectory(lib)
add_subdirectory(bin)
+190 -190
Просмотреть файл
@@ -24,6 +24,9 @@
#include "fwd.hpp"
#include "omnitrace.hpp"
#include <string>
#include <vector>
static int expect_error = NO_ERROR;
static int error_print = 0;
@@ -513,6 +516,49 @@ get_whole_function_names()
#endif
}
//======================================================================================//
//
// Helper functions because the syntax for getting a function or module name is unwieldy
//
std::string_view
get_name(procedure_t* _func)
{
static auto _v = std::unordered_map<procedure_t*, std::string>{};
auto itr = _v.find(_func);
if(itr == _v.end())
{
_v.emplace(_func, (_func) ? _func->getDemangledName() : std::string{});
}
return _v.at(_func);
}
std::string_view
get_name(module_t* _module)
{
static auto _v = std::unordered_map<module_t*, std::string>{};
auto itr = _v.find(_module);
if(itr == _v.end())
{
char _name[FUNCNAMELEN + 1];
memset(_name, '\0', FUNCNAMELEN + 1);
if(_module)
{
_module->getFullName(_name, FUNCNAMELEN);
_v.emplace(_module, std::string{ _name });
}
else
{
_v.emplace(nullptr, std::string{});
}
}
return _v.at(_module);
}
//======================================================================================//
//
// For selective instrumentation (unused)
@@ -523,6 +569,69 @@ are_file_include_exclude_lists_empty()
return true;
}
namespace
{
std::string
get_return_type(procedure_t* func)
{
if(func && func->isInstrumentable() && func->getReturnType())
return func->getReturnType()->getName();
return std::string{};
}
auto
get_parameter_types(procedure_t* func)
{
auto _param_names = std::vector<std::string>{};
if(func && func->isInstrumentable())
{
auto* _params = func->getParams();
if(_params)
{
_param_names.reserve(_params->size());
for(auto* itr : *_params)
{
std::string _name = itr->getType()->getName();
if(_name.empty()) _name = itr->getName();
_param_names.emplace_back(_name);
}
}
}
return _param_names;
}
} // namespace
//======================================================================================//
//
// We create a new name that embeds the file and line information in the name
//
function_signature
get_func_file_line_info(module_t* module, procedure_t* func)
{
using address_t = Dyninst::Address;
auto _file_name = get_name(module);
auto _func_name = get_name(func);
auto _return_type = get_return_type(func);
auto _param_types = get_parameter_types(func);
auto _base_addr = address_t{};
auto _last_addr = address_t{};
auto _src_lines = std::vector<statement_t>{};
if(func->getAddressRange(_base_addr, _last_addr) &&
module->getSourceLines(_base_addr, _src_lines) && !_src_lines.empty())
{
auto _row = _src_lines.front().lineNumber();
return function_signature(_return_type, _func_name, _file_name, _param_types,
{ _row, 0 }, { 0, 0 }, false, true, false);
}
else
{
return function_signature(_return_type, _func_name, _file_name, _param_types,
{ 0, 0 }, { 0, 0 }, false, false, false);
}
}
//======================================================================================//
//
// Gets information (line number, filename, and column number) about
@@ -532,173 +641,84 @@ function_signature
get_loop_file_line_info(module_t* module, procedure_t* func, flow_graph_t*,
basic_loop_t* loopToInstrument)
{
std::vector<BPatch_basicBlock*> basic_blocks{};
auto basic_blocks = std::vector<BPatch_basicBlock*>{};
loopToInstrument->getLoopBasicBlocksExclusive(basic_blocks);
if(basic_blocks.empty()) return function_signature{ "", "", "" };
auto base_addr = basic_blocks.front()->getStartAddress();
auto last_addr = basic_blocks.front()->getEndAddress();
basic_block_t* block = basic_blocks.front();
auto* _block = basic_blocks.front();
auto _base_addr = _block->getStartAddress();
auto _last_addr = _block->getEndAddress();
for(const auto& itr : basic_blocks)
{
if(itr == block) continue;
if(itr->dominates(block))
if(itr == _block) continue;
if(itr->dominates(_block))
{
base_addr = itr->getStartAddress();
last_addr = itr->getEndAddress();
block = itr;
_base_addr = itr->getStartAddress();
_last_addr = itr->getEndAddress();
_block = itr;
}
}
verbprintf(4, "Loop: size = %lu: base_addr = %lu, last_addr = %lu\n",
(unsigned long) (last_addr - base_addr), base_addr, last_addr);
auto _file_name = get_name(module);
auto _func_name = get_name(func);
auto _return_type = get_return_type(func);
auto _param_types = get_parameter_types(func);
auto _lines_beg = std::vector<statement_t>{};
auto _lines_end = std::vector<statement_t>{};
char fname[FUNCNAMELEN + 1];
char mname[FUNCNAMELEN + 1];
std::string typeName = {};
memset(fname, '\0', FUNCNAMELEN + 1);
memset(mname, '\0', FUNCNAMELEN + 1);
module->getFullName(mname, FUNCNAMELEN);
func->getName(fname, FUNCNAMELEN);
auto* returnType = func->getReturnType();
if(returnType) typeName = returnType->getName();
auto* params = func->getParams();
std::vector<string_t> _params;
if(params)
{
for(auto* itr : *params)
{
string_t _name = itr->getType()->getName();
if(_name.empty()) _name = itr->getName();
_params.push_back(_name);
}
}
bpvector_t<BPatch_statement> lines{};
bpvector_t<BPatch_statement> linesEnd{};
bool info1 = module->getSourceLines(base_addr, lines);
string_t filename = mname;
if(info1)
if(module->getSourceLines(_base_addr, _lines_beg))
{
// filename = lines[0].fileName();
int row1 = 0;
int col1 = 0;
for(auto& itr : lines)
int _row1 = 0;
int _col1 = 0;
for(auto& itr : _lines_beg)
{
if(itr.lineNumber() > 0)
{
row1 = itr.lineNumber();
col1 = itr.lineOffset();
_row1 = itr.lineNumber();
_col1 = itr.lineOffset();
break;
}
}
if(row1 == 0 && col1 == 0)
return function_signature(typeName, fname, filename, _params);
if(_row1 == 0 && _col1 == 0)
return function_signature(_return_type, _func_name, _file_name, _param_types);
int row2 = 0;
int col2 = 0;
for(auto& itr : lines)
int _row2 = 0;
int _col2 = 0;
for(auto& itr : _lines_beg)
{
row2 = std::max(row2, itr.lineNumber());
col2 = std::max(col2, itr.lineOffset());
_row2 = std::max(_row2, itr.lineNumber());
_col2 = std::max(_col2, itr.lineOffset());
}
if(col1 < 0) col1 = 0;
if(_col1 < 0) _col1 = 0;
bool info2 = module->getSourceLines(last_addr, linesEnd);
verbprintf(4, "size of linesEnd = %lu\n", (unsigned long) linesEnd.size());
if(info2)
if(module->getSourceLines(_last_addr, _lines_end))
{
for(auto& itr : linesEnd)
for(auto& itr : _lines_end)
{
row2 = std::max(row2, itr.lineNumber());
col2 = std::max(col2, itr.lineOffset());
_row2 = std::max(_row2, itr.lineNumber());
_col2 = std::max(_col2, itr.lineOffset());
}
if(col2 < 0) col2 = 0;
if(row2 < row1) row1 = row2; // Fix for wrong line numbers
if(_col2 < 0) _col2 = 0;
if(_row2 < _row1) _row1 = _row2; // Fix for wrong line numbers
return function_signature(typeName, fname, filename, _params, { row1, row2 },
{ col1, col2 }, true, info1, info2);
return function_signature(_return_type, _func_name, _file_name, _param_types,
{ _row1, _row2 }, { _col1, _col2 }, true, true,
true);
}
else
{
return function_signature(typeName, fname, filename, _params, { row1, 0 },
{ col1, 0 }, true, info1, info2);
return function_signature(_return_type, _func_name, _file_name, _param_types,
{ _row1, 0 }, { _col1, 0 }, true, true, false);
}
}
else
{
return function_signature(typeName, fname, filename, _params, { 0, 0 }, { 0, 0 },
true, false, false);
}
}
//======================================================================================//
//
// We create a new name that embeds the file and line information in the name
//
function_signature
get_func_file_line_info(module_t* module, procedure_t* func)
{
using address_t = Dyninst::Address;
char fname[FUNCNAMELEN + 1];
char mname[FUNCNAMELEN + 1];
string_t typeName = {};
memset(fname, '\0', FUNCNAMELEN + 1);
memset(mname, '\0', FUNCNAMELEN + 1);
module->getFullName(mname, FUNCNAMELEN);
func->getName(fname, FUNCNAMELEN);
address_t base_addr{};
address_t last_addr{};
func->getAddressRange(base_addr, last_addr);
auto* returnType = func->getReturnType();
if(returnType) typeName = returnType->getName();
auto* params = func->getParams();
std::vector<string_t> _params = {};
if(params)
{
_params.reserve(params->size());
for(auto* itr : *params)
{
string_t _name = itr->getType()->getName();
if(_name.empty()) _name = itr->getName();
_params.emplace_back(_name);
}
}
bpvector_t<BPatch_statement> lines = {};
bool info = module->getSourceLines(base_addr, lines);
string_t filename = mname;
if(info && !lines.empty())
{
auto row = lines.front().lineNumber();
return function_signature(typeName, fname, filename, _params, { row, 0 },
{ 0, 0 }, false, info, false);
}
else
{
return function_signature(typeName, fname, filename, _params, { 0, 0 }, { 0, 0 },
false, false, false);
return function_signature(_return_type, _func_name, _file_name, _param_types,
{ 0, 0 }, { 0, 0 }, true, false, false);
}
}
@@ -713,89 +733,69 @@ get_basic_block_file_line_info(module_t* module, procedure_t* func)
std::map<basic_block_t*, basic_block_signature> _data{};
if(!func) return _data;
auto* _cfg = func->getCFG();
std::set<BPatch_basicBlock*> _basic_blocks{};
auto* _cfg = func->getCFG();
auto _basic_blocks = std::set<BPatch_basicBlock*>{};
_cfg->getAllBasicBlocks(_basic_blocks);
if(_basic_blocks.empty()) return _data;
char fname[FUNCNAMELEN + 1];
char mname[FUNCNAMELEN + 1];
std::string typeName = {};
memset(fname, '\0', FUNCNAMELEN + 1);
memset(mname, '\0', FUNCNAMELEN + 1);
module->getFullName(mname, FUNCNAMELEN);
func->getName(fname, FUNCNAMELEN);
auto* returnType = func->getReturnType();
if(returnType) typeName = returnType->getName();
auto* params = func->getParams();
std::vector<string_t> _params;
if(params)
{
for(auto* itr : *params)
{
string_t _name = itr->getType()->getName();
if(_name.empty()) _name = itr->getName();
_params.push_back(_name);
}
}
auto _file_name = get_name(module);
auto _func_name = get_name(func);
auto _return_type = get_return_type(func);
auto _param_types = get_parameter_types(func);
for(auto&& itr : _basic_blocks)
{
auto base_addr = itr->getStartAddress();
auto last_addr = itr->getEndAddress();
auto _base_addr = itr->getStartAddress();
auto _last_addr = itr->getEndAddress();
verbprintf(4, "BB: size = %lu: base_addr = %lu, last_addr = %lu\n",
(unsigned long) (last_addr - base_addr), base_addr, last_addr);
verbprintf(4,
"[%s][%s] basic_block: size = %lu: base_addr = %lu, last_addr = %lu\n",
_file_name.data(), _func_name.data(),
(unsigned long) (_last_addr - _base_addr), _base_addr, _last_addr);
bpvector_t<BPatch_statement> linesBeg{};
bpvector_t<BPatch_statement> linesEnd{};
auto _lines_beg = std::vector<statement_t>{};
auto _lines_end = std::vector<statement_t>{};
string_t filename = mname;
if(module->getSourceLines(base_addr, linesBeg) && !linesBeg.empty())
if(module->getSourceLines(_base_addr, _lines_beg) && !_lines_beg.empty())
{
int row1 = linesBeg.front().lineNumber();
int col1 = linesBeg.front().lineOffset();
int _row1 = _lines_beg.front().lineNumber();
int _col1 = _lines_beg.front().lineOffset();
verbprintf(4, "size of linesEnd = %lu\n", (unsigned long) linesEnd.size());
verbprintf(4, "size of _lines_end = %lu\n",
(unsigned long) _lines_end.size());
if(module->getSourceLines(last_addr, linesEnd) && !linesEnd.empty())
if(module->getSourceLines(_last_addr, _lines_end) && !_lines_end.empty())
{
int row2 = linesEnd.back().lineNumber();
int col2 = linesEnd.back().lineOffset();
int _row2 = _lines_end.back().lineNumber();
int _col2 = _lines_end.back().lineOffset();
if(row2 < row1) std::swap(row1, row2);
if(row1 == row2 && col2 < col1) std::swap(col1, col2);
if(_row2 < _row1) std::swap(_row1, _row2);
if(_row1 == _row2 && _col2 < _col1) std::swap(_col1, _col2);
_data.emplace(itr,
basic_block_signature{
base_addr, last_addr,
function_signature(typeName, fname, filename, _params,
{ row1, row2 }, { col1, col2 }, true,
true, true) });
_data.emplace(
itr, basic_block_signature{
_base_addr, _last_addr,
function_signature(_return_type, _func_name, _file_name,
_param_types, { _row1, _row2 },
{ _col1, _col2 }, true, true, true) });
}
else
{
_data.emplace(itr,
basic_block_signature{
base_addr, last_addr,
function_signature(typeName, fname, filename, _params,
{ row1, 0 }, { col1, 0 }, true, true,
false) });
_base_addr, _last_addr,
function_signature(_return_type, _func_name, _file_name,
_param_types, { _row1, 0 },
{ _col1, 0 }, true, true, false) });
}
}
else
{
_data.emplace(itr,
basic_block_signature{
base_addr, last_addr,
function_signature(typeName, fname, filename, _params) });
_data.emplace(itr, basic_block_signature{
_base_addr, _last_addr,
function_signature(_return_type, _func_name,
_file_name, _param_types) });
}
}
@@ -861,7 +861,7 @@ find_function(image_t* app_image, const std::string& _name, const strset_t& _ext
{
if(_name.empty()) return nullptr;
auto _find = [app_image](const string_t& _f) -> procedure_t* {
auto _find = [app_image](const std::string& _f) -> procedure_t* {
// Extract the vector of functions
bpvector_t<procedure_t*> _found;
auto* ret = app_image->findFunction(_f.c_str(), _found, false, true, true);
+14 -13
Просмотреть файл
@@ -22,25 +22,26 @@
#include "function_signature.hpp"
function_signature::function_signature(string_t _ret, const string_t& _name,
string_t _file, location_t _row, location_t _col,
bool _loop, bool _info_beg, bool _info_end)
function_signature::function_signature(std::string_view _ret, std::string_view _name,
std::string_view _file, location_t _row,
location_t _col, bool _loop, bool _info_beg,
bool _info_end)
: m_loop(_loop)
, m_info_beg(_info_beg)
, m_info_end(_info_end)
, m_row(std::move(_row))
, m_col(std::move(_col))
, m_return(std::move(_ret))
, m_name(tim::demangle(_name))
, m_file(std::move(_file))
, m_return(_ret)
, m_name(tim::demangle(_name.data()))
, m_file(_file)
{
if(m_file.find('/') != string_t::npos)
if(m_file.find('/') != std::string_view::npos)
m_file = m_file.substr(m_file.find_last_of('/') + 1);
}
function_signature::function_signature(const string_t& _ret, const string_t& _name,
const string_t& _file,
const std::vector<string_t>& _params,
function_signature::function_signature(std::string_view _ret, std::string_view _name,
std::string_view _file,
const std::vector<std::string>& _params,
location_t _row, location_t _col, bool _loop,
bool _info_beg, bool _info_end)
: function_signature(_ret, _name, _file, _row, _col, _loop, _info_beg, _info_end)
@@ -52,13 +53,13 @@ function_signature::function_signature(const string_t& _ret, const string_t& _na
m_params += ")";
}
string_t
std::string
function_signature::get(function_signature& sig)
{
return sig.get();
}
string_t
std::string
function_signature::get(bool _all, bool _save) const
{
if(!_all && _save && !m_signature.empty()) return m_signature;
@@ -103,7 +104,7 @@ function_signature::get(bool _all, bool _save) const
return ss.str();
}
string_t
std::string
function_signature::get_coverage(bool _basic_block) const
{
std::stringstream ss;
+36 -20
Просмотреть файл
@@ -24,49 +24,65 @@
#include "fwd.hpp"
#include <tuple>
struct function_signature
{
using location_t = std::pair<unsigned long, unsigned long>;
TIMEMORY_DEFAULT_OBJECT(function_signature)
function_signature(string_t _ret, const string_t& _name, string_t _file,
function_signature(std::string_view _ret, std::string_view _name,
std::string_view _file, location_t _row = { 0, 0 },
location_t _col = { 0, 0 }, bool _loop = false,
bool _info_beg = false, bool _info_end = false);
function_signature(std::string_view _ret, std::string_view _name,
std::string_view _file, const std::vector<std::string>& _params,
location_t _row = { 0, 0 }, location_t _col = { 0, 0 },
bool _loop = false, bool _info_beg = false,
bool _info_end = false);
function_signature(const string_t& _ret, const string_t& _name, const string_t& _file,
const std::vector<string_t>& _params, location_t _row = { 0, 0 },
location_t _col = { 0, 0 }, bool _loop = false,
bool _info_beg = false, bool _info_end = false);
function_signature& set_loop_number(uint32_t _n)
{
m_loop_num = _n;
return *this;
}
static string_t get(function_signature& sig);
string_t get(bool _all = false, bool _save = true) const;
string_t get_coverage(bool _is_basic_block) const;
static std::string get(function_signature& sig);
std::string get(bool _all = false, bool _save = true) const;
std::string get_coverage(bool _is_basic_block) const;
bool m_loop = false;
bool m_info_beg = false;
bool m_info_end = false;
uint32_t m_loop_num = std::numeric_limits<uint32_t>::max();
location_t m_row = { 0, 0 };
location_t m_col = { 0, 0 };
string_t m_return = {};
string_t m_name = {};
string_t m_params = "()";
string_t m_file = {};
mutable string_t m_signature = {};
bool m_loop = false;
bool m_info_beg = false;
bool m_info_end = false;
uint32_t m_loop_num = std::numeric_limits<uint32_t>::max();
location_t m_row = { 0, 0 };
location_t m_col = { 0, 0 };
std::string m_return = {};
std::string m_name = {};
std::string m_params = "()";
std::string m_file = {};
mutable std::string m_signature = {};
friend bool operator==(const function_signature& lhs, const function_signature& rhs)
{
return lhs.get() == rhs.get();
}
friend bool operator<(const function_signature& lhs, const function_signature& rhs)
{
const auto loop_max = std::numeric_limits<uint32_t>::max();
if(lhs.m_loop && !rhs.m_loop) return false;
if(!lhs.m_loop && rhs.m_loop) return true;
if(lhs.m_loop_num < loop_max && rhs.m_loop_num == loop_max) return false;
if(lhs.m_loop_num == loop_max && rhs.m_loop_num < loop_max) return true;
return std::tie(lhs.m_file, lhs.m_name, lhs.m_return, lhs.m_params,
lhs.m_row.first, lhs.m_col.first, lhs.m_loop_num) <
std::tie(rhs.m_file, rhs.m_name, rhs.m_return, rhs.m_params,
rhs.m_row.first, rhs.m_col.first, rhs.m_loop_num);
}
template <typename ArchiveT>
void serialize(ArchiveT& _ar, const unsigned)
{
+18
Просмотреть файл
@@ -42,11 +42,14 @@
#include <BPatch_callbacks.h>
#include <BPatch_function.h>
#include <BPatch_instruction.h>
#include <BPatch_object.h>
#include <BPatch_point.h>
#include <BPatch_process.h>
#include <BPatch_snippet.h>
#include <BPatch_statement.h>
#include <Instruction.h>
#include <Symtab.h>
#include <SymtabReader.h>
#include <dyntypes.h>
#include <climits>
@@ -66,6 +69,7 @@
#include <string>
#include <string_view>
#include <unistd.h>
#include <unordered_map>
#include <vector>
#define MUTNAMELEN 1024
@@ -111,9 +115,12 @@ using basic_block_t = BPatch_basicBlock;
using basic_loop_t = BPatch_basicBlockLoop;
using procedure_loc_t = BPatch_procedureLocation;
using point_t = BPatch_point;
using object_t = BPatch_object;
using local_var_t = BPatch_localVar;
using sequence_t = BPatch_sequence;
using const_expr_t = BPatch_constExpr;
using error_level_t = BPatchErrorLevel;
using snippet_handle_t = BPatchSnippetHandle;
using patch_pointer_t = std::shared_ptr<patch_t>;
using snippet_pointer_t = std::shared_ptr<snippet_t>;
using call_expr_pointer_t = std::shared_ptr<call_expr_t>;
@@ -166,6 +173,11 @@ extern bool debug_print;
extern bool instr_print;
extern int verbose_level;
//
// instrumentation settings
//
extern bool simulate;
extern bool include_uninstr;
//
// string settings
//
extern string_t main_fname;
@@ -297,3 +309,9 @@ error_func_real(error_level_t level, int num, const char* const* params);
void
error_func_fake(error_level_t level, int num, const char* const* params);
std::string_view
get_name(procedure_t* _module);
std::string_view
get_name(module_t* _module);
+30 -26
Просмотреть файл
@@ -55,44 +55,48 @@ module_function::module_function(module_t* mod, procedure_t* proc)
: module{ mod }
, function{ proc }
, flow_graph{ proc->getCFG() }
, module_name{ get_name(module) }
, function_name{ get_name(function) }
{
if(flow_graph)
{
flow_graph->getAllBasicBlocks(basic_blocks);
flow_graph->getOuterLoops(loop_blocks);
}
instructions.reserve(basic_blocks.size());
for(const auto& itr : basic_blocks)
{
std::vector<instruction_t> _instructions{};
itr->getInstructions(_instructions);
num_instructions += _instructions.size();
if(debug_print || verbose_level > 3 || instr_print)
instructions.emplace_back(std::move(_instructions));
}
char modname[FUNCNAMELEN];
char fname[FUNCNAMELEN];
module->getFullName(modname, FUNCNAMELEN);
function->getName(fname, FUNCNAMELEN);
module_name = modname;
function_name = fname;
signature = get_func_file_line_info(module, function);
if(!function->isInstrumentable())
{
verbprintf(0,
verbprintf(1,
"Warning! module function generated for un-instrumentable "
"function: %s [%s]\n",
function_name.c_str(), module_name.c_str());
}
std::pair<address_t, address_t> _range{};
auto _range = std::pair<address_t, address_t>{};
if(function->getAddressRange(_range.first, _range.second))
{
start_address = _range.first;
address_range = _range.second - _range.first;
}
signature = get_func_file_line_info(module, function);
if(function->isInstrumentable())
{
// this information is potentially not available and
// appears to be the cause of a segfault in testing
// so only attempt to extract it for instrumentable
// functions
if(flow_graph)
{
flow_graph->getAllBasicBlocks(basic_blocks);
flow_graph->getOuterLoops(loop_blocks);
}
instructions.reserve(basic_blocks.size());
for(const auto& itr : basic_blocks)
{
std::vector<instruction_t> _instructions{};
itr->getInstructions(_instructions);
num_instructions += _instructions.size();
if(debug_print || verbose_level > 3 || instr_print)
instructions.emplace_back(std::move(_instructions));
}
}
}
void
+9 -9
Просмотреть файл
@@ -30,6 +30,7 @@
#include <sstream>
#include <string>
#include <tuple>
struct module_function
{
@@ -117,19 +118,18 @@ public:
friend bool operator<(const module_function& lhs, const module_function& rhs)
{
return (lhs.module_name == rhs.module_name)
? ((lhs.function_name == rhs.function_name)
? (lhs.signature.get() < rhs.signature.get())
: (lhs.function_name < rhs.function_name))
: (lhs.module_name < rhs.module_name);
return std::tie(lhs.module_name, lhs.start_address, lhs.function_name,
lhs.address_range, lhs.num_instructions, lhs.signature) <
std::tie(rhs.module_name, rhs.start_address, rhs.function_name,
rhs.address_range, rhs.num_instructions, rhs.signature);
}
friend bool operator==(const module_function& lhs, const module_function& rhs)
{
return std::tie(lhs.module_name, lhs.function_name, lhs.signature,
lhs.address_range, lhs.num_instructions) ==
std::tie(rhs.module_name, rhs.function_name, rhs.signature,
rhs.address_range, rhs.num_instructions);
return std::tie(lhs.module_name, lhs.start_address, lhs.function_name,
lhs.address_range, lhs.num_instructions, lhs.signature) ==
std::tie(rhs.module_name, rhs.start_address, rhs.function_name,
rhs.address_range, rhs.num_instructions, rhs.signature);
}
friend std::ostream& operator<<(std::ostream& os, const module_function& rhs)
+235 -160
Просмотреть файл
@@ -23,19 +23,23 @@
#include "omnitrace.hpp"
#include "fwd.hpp"
#include <cstring>
#include <iterator>
#include <timemory/config.hpp>
#include <timemory/hash.hpp>
#include <timemory/manager.hpp>
#include <timemory/settings.hpp>
#include <timemory/utility/console.hpp>
#include <timemory/utility/demangle.hpp>
#include <algorithm>
#include <chrono>
#include <csignal>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iterator>
#include <map>
#include <regex>
#include <stdexcept>
@@ -43,6 +47,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <thread>
#include <tuple>
#include <utility>
#include <vector>
@@ -70,6 +75,8 @@ size_t min_loop_instructions = (1 << 6); // 64
bool werror = false;
bool debug_print = false;
bool instr_print = false;
bool simulate = false;
bool include_uninstr = false;
int verbose_level = tim::get_env<int>("OMNITRACE_VERBOSE_INSTRUMENT", 0);
string_t main_fname = "main";
string_t argv0 = {};
@@ -103,8 +110,8 @@ bool binary_rewrite = false;
bool is_attached = false;
bool use_mpi = false;
bool is_static_exe = false;
bool simulate = false;
bool include_uninstr = false;
bool force_config = false;
bool parse_all_modules = false;
size_t batch_size = 50;
strset_t extra_libs = {};
std::vector<std::pair<uint64_t, string_t>> hash_ids = {};
@@ -126,6 +133,8 @@ string_t print_excluded = {};
string_t print_available = {};
string_t print_overlapping = {};
strset_t print_formats = { "txt", "json" };
strvec_t libname_suffixes = {};
strvec_t libname_fallbacks = {};
std::string modfunc_dump_dir = {};
auto regex_opts = std::regex_constants::egrep | std::regex_constants::optimize;
@@ -271,12 +280,6 @@ main(int argc, char** argv)
parser.add_argument({ "" }, "");
parser.add_argument({ "[DEBUG OPTIONS]" }, "");
parser.add_argument({ "" }, "");
parser.add_argument({ "--debug" }, "Debug output")
.max_count(1)
.action([](parser_t& p) {
debug_print = p.get<bool>("debug");
if(debug_print && !p.exists("verbose")) verbose_level = 256;
});
parser.add_argument({ "-v", "--verbose" }, "Verbose output")
.max_count(1)
.action([](parser_t& p) {
@@ -289,6 +292,12 @@ main(int argc, char** argv)
.dtype("boolean")
.max_count(1)
.action([](parser_t& p) { werror = p.get<bool>("error"); });
parser.add_argument({ "--debug" }, "Debug output")
.max_count(1)
.action([](parser_t& p) {
debug_print = p.get<bool>("debug");
if(debug_print && !p.exists("verbose")) verbose_level = 256;
});
parser
.add_argument({ "--simulate" },
"Exit after outputting diagnostic "
@@ -406,6 +415,16 @@ main(int argc, char** argv)
if(instr_mode == "coverage" && !p.exists("coverage"))
coverage_mode = CODECOV_FUNCTION;
});
parser
.add_argument(
{ "-f", "--force" },
"Force the command-line argument configuration, i.e. don't get cute. Useful "
"for forcing runtime instrumentation of an executable that [A] Dyninst "
"thinks is a library after reading ELF and [B] whose name makes it look like "
"a library (e.g. starts with 'lib' and/or ends in '.so', '.so.*', or '.a')")
.max_count(1)
.action([](parser_t& p) { force_config = p.get<bool>("force"); });
if(_cmdc == 0)
{
parser
@@ -616,6 +635,14 @@ main(int argc, char** argv)
.dtype("int")
.action(
[](parser_t& p) { min_instructions = p.get<size_t>("min-instructions"); });
parser
.add_argument({ "-r", "--min-address-range" },
"If the address range of a function is less than this value, "
"exclude it from instrumentation")
.count(1)
.dtype("int")
.action(
[](parser_t& p) { min_address_range = p.get<size_t>("min-address-range"); });
parser
.add_argument({ "--min-instructions-loop" },
"If the number of instructions in a function containing a loop is "
@@ -625,14 +652,6 @@ main(int argc, char** argv)
.action([](parser_t& p) {
min_loop_instructions = p.get<size_t>("min-instructions-loop");
});
parser
.add_argument({ "-r", "--min-address-range" },
"If the address range of a function is less than this value, "
"exclude it from instrumentation")
.count(1)
.dtype("int")
.action(
[](parser_t& p) { min_address_range = p.get<size_t>("min-address-range"); });
parser
.add_argument({ "--min-address-range-loop" },
"If the address range of a function containing a loop is less than "
@@ -642,7 +661,13 @@ main(int argc, char** argv)
.action([](parser_t& p) {
min_loop_address_range = p.get<size_t>("min-address-range-loop");
});
parser.add_argument({ "--coverage" }, "Enable recording the code coverage")
parser
.add_argument(
{ "--coverage" },
"Enable recording the code coverage. If instrumenting in coverage mode ('-M "
"converage'), this simply specifies the granularity. If instrumenting in "
"trace or sampling mode, this enables recording code-coverage in addition to "
"the instrumentation of that mode (if any).")
.max_count(1)
.choices({ "none", "function", "basic_block" })
.action([](parser_t& p) {
@@ -691,8 +716,20 @@ main(int argc, char** argv)
"Allow dyninst to instrument either multiple functions which overlap (share "
"part of same function body) or single functions with multiple entry points. "
"For more info, see Section 2 of the DyninstAPI documentation.")
.count(0)
.action([](parser_t&) { allow_overlapping = true; });
.max_count(1)
.action(
[](parser_t& p) { allow_overlapping = p.get<bool>("allow-overlapping"); });
parser
.add_argument(
{ "--parse-all-modules" },
"By default, omnitrace simply requests Dyninst to provide all the procedures "
"in the application image. If this option is enabled, omnitrace will iterate "
"over all the modules and extract the functions. Theoretically, it should be "
"the same but the data is slightly different, possibly due to weak binding "
"scopes. In general, enabling option will probably have no visible effect")
.max_count(1)
.action(
[](parser_t& p) { parse_all_modules = p.get<bool>("parse-all-modules"); });
parser.add_argument({ "" }, "");
parser.add_argument({ "[DYNINST OPTIONS]" }, "");
@@ -824,6 +861,75 @@ main(int argc, char** argv)
!parser.exists("min-instructions") &&
!parser.exists("min-address-range-loop"));
auto _omnitrace_exe_path = tim::dirname(::get_realpath("/proc/self/exe"));
verbprintf(4, "omnitrace exe path: %s\n", _omnitrace_exe_path.c_str());
if(strcmp(::basename(_omnitrace_exe_path.c_str()), "bin") == 0)
{
libname_suffixes.emplace_back("omnitrace");
libname_suffixes.emplace_back("../lib");
libname_suffixes.emplace_back("../lib64");
libname_suffixes.emplace_back("../lib/omnitrace");
libname_suffixes.emplace_back("../lib64/omnitrace");
libname_suffixes.emplace_back("lib");
libname_suffixes.emplace_back("lib64");
libname_suffixes.emplace_back("lib/omnitrace");
libname_suffixes.emplace_back("lib64/omnitrace");
libname_fallbacks.emplace_back(_omnitrace_exe_path);
}
else
{
libname_suffixes.emplace_back("lib");
libname_suffixes.emplace_back("lib64");
libname_suffixes.emplace_back("lib/omnitrace");
libname_suffixes.emplace_back("lib64/omnitrace");
libname_fallbacks.emplace_back(tim::get_env<std::string>("PWD", "."));
}
if(_cmdv && _cmdv[0] && strlen(_cmdv[0]) > 0)
{
auto _is_executable = omnitrace_get_is_executable(_cmdv[0], binary_rewrite);
std::string _cmdv_base = ::basename(_cmdv[0]);
auto _has_lib_suffix = _cmdv_base.length() > 3 &&
(_cmdv_base.find(".so.") != std::string::npos ||
_cmdv_base.find(".so") == (_cmdv_base.length() - 3) ||
_cmdv_base.find(".a") == (_cmdv_base.length() - 2));
auto _has_lib_prefix = _cmdv_base.length() > 3 && _cmdv_base.find("lib") == 0;
if(!force_config && !_is_executable && !binary_rewrite &&
(_has_lib_prefix || _has_lib_suffix))
{
fflush(stdout);
std::stringstream _separator{};
// 18 is approximate length of '[omnitrace][exe] '
// 32 is approximate length of 'Warning! "" is not executable!'
size_t _width =
std::min<size_t>(std::get<0>(tim::utility::console::get_columns()) - 18,
strlen(_cmdv[0]) + 32);
_separator.fill('=');
_separator << "#" << std::setw(_width - 2) << ""
<< "#";
verbprintf(0, "%s\n", _separator.str().c_str());
verbprintf(0, "\n");
verbprintf(0, "Warning! '%s' is not executable!\n", _cmdv[0]);
verbprintf(0, "Runtime instrumentation is not possible!\n");
verbprintf(0, "Switching to binary rewrite mode and assuming '--simulate "
"--all-functions'\n");
verbprintf(
0, "(which will provide an approximation for runtime instrumentation)\n");
verbprintf(1, "%s :: (^lib)=%s, (.so$|.a$|.so.*)=%s\n", _cmdv_base.c_str(),
(_has_lib_prefix) ? "true" : "false",
(_has_lib_suffix) ? "true" : "false");
verbprintf(0, "\n");
verbprintf(0, "%s\n", _separator.str().c_str());
verbprintf(0, "\n");
fflush(stdout);
std::this_thread::sleep_for(std::chrono::milliseconds{ 500 });
binary_rewrite = true;
simulate = true;
include_uninstr = true;
}
}
if(binary_rewrite && outfile.empty())
{
auto _is_local = (get_realpath(cmdv0) ==
@@ -1020,6 +1126,22 @@ main(int argc, char** argv)
errprintf(-1, "address space for dynamic instrumentation was not created\n");
}
if(dynamic_cast<binary_edit_t*>(addr_space) != nullptr &&
dynamic_cast<process_t*>(addr_space) != nullptr)
{
errprintf(-1, "address space statisfied dynamic_cast<%s> and dynamic_cast<%s>.\n",
tim::demangle<binary_edit_t*>().c_str(),
tim::demangle<process_t*>().c_str());
}
auto _rewrite = (dynamic_cast<binary_edit_t*>(addr_space) != nullptr &&
dynamic_cast<process_t*>(addr_space) == nullptr);
if(_rewrite != binary_rewrite)
{
errprintf(-1, "binary rewrite was %s but has been deduced to be %s\n",
(binary_rewrite) ? "ON" : "OFF", (_rewrite) ? "ON" : "OFF");
}
process_t* app_thread = nullptr;
binary_edit_t* app_binary = nullptr;
@@ -1028,8 +1150,8 @@ main(int argc, char** argv)
image_t* app_image = addr_space->getImage();
bpvector_t<module_t*>* app_modules = app_image->getModules();
bpvector_t<procedure_t*>* app_functions = app_image->getProcedures(include_uninstr);
bpvector_t<module_t*> modules;
bpvector_t<procedure_t*> functions;
std::set<module_t*> modules = {};
std::set<procedure_t*> functions = {};
//----------------------------------------------------------------------------------//
//
@@ -1058,47 +1180,24 @@ main(int argc, char** argv)
}
};
if(app_modules && !app_modules->empty())
{
modules.reserve(app_modules->size());
for(auto* itr : *app_modules)
{
if(!itr->isSystemLib()) modules.emplace_back(itr);
}
for(auto* itr : modules)
{
auto* procedures = itr->getProcedures(include_uninstr);
if(procedures)
{
for(auto* pitr : *procedures)
{
if(!pitr->isInstrumentable()) continue;
auto _modfn = module_function{ itr, pitr };
module_names.insert(_modfn.module_name);
_insert_module_function(available_module_functions, _modfn);
_add_overlapping(itr, pitr);
}
}
}
}
else
{
verbprintf(0, "Warning! No modules in application...\n");
}
if(app_functions && !app_functions->empty())
{
functions.reserve(app_functions->size());
for(auto* itr : *app_functions)
{
if(!itr->getModule()->isSystemLib()) functions.emplace_back(itr);
if(itr->getModule() && !itr->getModule()->isSystemLib())
{
functions.emplace(itr);
modules.emplace(itr->getModule());
}
}
verbprintf(2, "Adding %zu procedures found in the app image...\n",
functions.size());
for(auto* itr : functions)
{
module_t* mod = itr->getModule();
if(mod && itr->isInstrumentable())
if(itr->isInstrumentable() || (simulate && include_uninstr))
{
auto _modfn = module_function{ mod, itr };
module_t* mod = itr->getModule();
auto _modfn = module_function{ mod, itr };
module_names.insert(_modfn.module_name);
_insert_module_function(available_module_functions, _modfn);
_add_overlapping(mod, itr);
@@ -1107,11 +1206,48 @@ main(int argc, char** argv)
}
else
{
verbprintf(0, "Warning! No functions in application...\n");
verbprintf(
0, "Warning! No functions in application. Enabling parsing all modules...\n");
parse_all_modules = true;
}
verbprintf(1, "Module size before loading instrumentation library: %lu\n",
(long unsigned) modules.size());
if(parse_all_modules && app_modules && !app_modules->empty())
{
for(auto* itr : *app_modules)
{
if(!itr->isSystemLib()) modules.emplace(itr);
}
verbprintf(2,
"Adding the procedures from %zu modules found in the app image...\n",
modules.size());
for(auto* itr : modules)
{
auto* procedures = itr->getProcedures(include_uninstr);
if(procedures)
{
verbprintf(2, "Processing %zu procedures found in the %s module...\n",
procedures->size(), get_name(itr).data());
for(auto* pitr : *procedures)
{
if(!pitr->isInstrumentable() && !simulate && !include_uninstr)
continue;
functions.emplace(pitr);
auto _modfn = module_function{ itr, pitr };
module_names.insert(_modfn.module_name);
_insert_module_function(available_module_functions, _modfn);
_add_overlapping(itr, pitr);
}
}
}
}
else if(parse_all_modules)
{
verbprintf(0, "Warning! No modules in application...\n");
}
verbprintf(1, "\n");
verbprintf(1, "Found %zu functions in %zu modules in instrumentation target\n",
functions.size(), modules.size());
if(debug_print || verbose_level > 2)
{
@@ -1221,8 +1357,6 @@ main(int argc, char** argv)
//
//----------------------------------------------------------------------------------//
auto* main_init = find_function(app_image, "_init");
auto* main_fini = find_function(app_image, "_fini");
auto* main_func = find_function(app_image, main_fname.c_str());
auto* user_start_func = find_function(app_image, "omnitrace_user_start_trace",
{ "omnitrace_user_start_thread_trace" });
@@ -1383,30 +1517,6 @@ main(int argc, char** argv)
//
//----------------------------------------------------------------------------------//
if(!main_func)
{
if(!main_init && !main_fini)
{
errprintf(-1, "could not find '%s', '_init' or '_fini', aborting...\n",
main_fname.c_str());
}
else if(!main_init)
{
errprintf(-1, "could not find '%s' or '_init', aborting...\n",
main_fname.c_str());
}
else if(!main_fini)
{
errprintf(-1, "could not find '%s' or '_fini', aborting...\n",
main_fname.c_str());
}
else
{
verbprintf(0, "using '%s' and '%s' in lieu of '%s'...\n", "_init", "_fini",
main_fname.c_str());
}
}
using pair_t = std::pair<procedure_t*, string_t>;
for(const auto& itr :
@@ -1423,26 +1533,6 @@ main(int argc, char** argv)
}
}
auto check_for_debug_info = [](bool& _has_debug_info, auto* _func) {
// This heuristic guesses that debugging info is available if function
// is not defined in the DEFAULT_MODULE
if(_func && !_has_debug_info)
{
module_t* _module = _func->getModule();
if(_module)
{
char moduleName[FUNCNAMELEN];
_module->getFullName(moduleName, FUNCNAMELEN);
if(strcmp(moduleName, "DEFAULT_MODULE") != 0) _has_debug_info = true;
}
}
};
bool has_debug_info = false;
check_for_debug_info(has_debug_info, main_func);
check_for_debug_info(has_debug_info, main_init);
check_for_debug_info(has_debug_info, main_fini);
//----------------------------------------------------------------------------------//
//
// Find the entry/exit point of either the main (if executable) or the _init
@@ -1460,16 +1550,6 @@ main(int argc, char** argv)
main_exit_points = main_func->findPoint(BPatch_exit);
verbprintf(2, "Done\n");
}
else
{
verbprintf(2, "Finding init entry... ");
main_entr_points = main_init->findPoint(BPatch_entry);
verbprintf(2, "Done\n");
verbprintf(2, "Finding fini exit... ");
main_exit_points = main_fini->findPoint(BPatch_exit);
verbprintf(2, "Done\n");
}
//----------------------------------------------------------------------------------//
//
@@ -1535,7 +1615,7 @@ main(int argc, char** argv)
if(_libname.empty()) _libname = get_absolute_lib_filepath(itr, "LIBRARY_PATH");
if(_libname.empty()) _libname = get_absolute_lib_filepath(itr, "LD_LIBRARY_PATH");
}
if(_libname.empty()) _libname = "libomnitrace.so";
if(_libname.empty()) _libname = "libomnitrace-dl.so";
// prioritize the user environment arguments
auto env_vars = parser.get<strvec_t>("env");
@@ -1634,13 +1714,10 @@ main(int argc, char** argv)
}
else
{
// in sampling mode, we instrument either main or init + fini
for(auto&& itr : { main_func, main_init, main_fini })
{
if(itr)
_insert_module_function(instrumented_module_functions,
module_function{ itr->getModule(), itr });
}
// in sampling mode, we instrument either main or add init and fini callbacks
if(main_func)
_insert_module_function(instrumented_module_functions,
module_function{ main_func->getModule(), main_func });
for(const auto& itr : available_module_functions)
{
@@ -1662,6 +1739,11 @@ main(int argc, char** argv)
//
//----------------------------------------------------------------------------------//
auto _objs = std::vector<object_t*>{};
addr_space->getImage()->getObjects(_objs);
auto _init_sequence = sequence_t{ init_names };
auto _fini_sequence = sequence_t{ fini_names };
if(app_thread && is_attached)
{
assert(app_thread != nullptr);
@@ -1674,16 +1756,26 @@ main(int argc, char** argv)
if(main_entr_points)
{
verbprintf(1, "Adding main entry snippets...\n");
addr_space->insertSnippet(BPatch_sequence(init_names), *main_entr_points,
addr_space->insertSnippet(_init_sequence, *main_entr_points,
BPatch_callBefore, BPatch_firstSnippet);
}
else
{
for(auto* itr : _objs)
itr->insertInitCallback(_init_sequence);
}
}
if(main_exit_points)
{
verbprintf(1, "Adding main exit snippets...\n");
addr_space->insertSnippet(BPatch_sequence(fini_names), *main_exit_points,
BPatch_callAfter, BPatch_firstSnippet);
addr_space->insertSnippet(_fini_sequence, *main_exit_points, BPatch_callAfter,
BPatch_firstSnippet);
}
else
{
for(auto* itr : _objs)
itr->insertFiniCallback(_fini_sequence);
}
//----------------------------------------------------------------------------------//
@@ -1716,13 +1808,11 @@ main(int argc, char** argv)
if(instr_mode != "coverage")
{
std::map<std::string, std::pair<size_t, size_t>> _pass_info{};
const int _pass_verbose_lvl = 0;
auto _pass_info = std::map<std::string, std::pair<size_t, size_t>>{};
const int _pass_verbose_lvl = 0;
for(const auto& itr : instrumented_module_functions)
{
bool _is_main = itr.function == main_func || itr.function == main_init ||
itr.function == main_fini;
if(_is_main) continue;
if(itr.function == main_func) continue;
auto _count = itr(addr_space, entr_trace, exit_trace);
_pass_info[itr.module_name].first += _count.first;
_pass_info[itr.module_name].second += _count.second;
@@ -1756,9 +1846,7 @@ main(int argc, char** argv)
const int _covr_verbose_lvl = 1;
for(const auto& itr : coverage_module_functions)
{
bool _is_main = itr.function == main_func || itr.function == main_init ||
itr.function == main_fini;
if(_is_main) continue;
if(itr.function == main_func) continue;
itr.register_source(addr_space, reg_src_func, *main_entr_points);
auto _count = itr.register_coverage(addr_space, reg_cov_func);
_covr_info[itr.module_name].first += _count.first;
@@ -1899,22 +1987,18 @@ main(int argc, char** argv)
{
for(const auto& itr : _modset)
{
std::stringstream _ss{};
_ss << std::boolalpha;
_ss << "" << itr.module_name << "] --> [" << itr.function_name << "]["
<< itr.num_instructions << "]";
_insert(itr.module_name, _ss.str());
_insert(itr.module_name, TIMEMORY_JOIN("", "[", itr.module_name,
"] --> [", itr.function_name, "][",
itr.num_instructions, "]"));
}
}
else if(_mode == "pair+")
{
for(const auto& itr : _modset)
{
std::stringstream _ss{};
_ss << std::boolalpha;
_ss << "[" << itr.module_name << "] --> [" << itr.signature.get() << "]["
<< itr.num_instructions << "]";
_insert(itr.module_name, _ss.str());
_insert(itr.module_name, TIMEMORY_JOIN("", "[", itr.module_name,
"] --> [", itr.signature.get(),
"][", itr.num_instructions, "]"));
}
}
else
@@ -2246,6 +2330,9 @@ get_absolute_lib_filepath(std::string lib_name, const std::string& env_path,
std::vector<std::string> suffixes,
std::vector<std::string> fallbacks)
{
if(suffixes.empty()) suffixes = libname_suffixes;
if(fallbacks.empty()) fallbacks = libname_fallbacks;
if(!lib_name.empty() && (!file_exists(lib_name) ||
std::regex_match(lib_name, std::regex("^[A-Za-z0-9].*"))))
{
@@ -2273,6 +2360,7 @@ get_absolute_lib_filepath(std::string lib_name, const std::string& env_path,
break;
}
}
if(file_exists(lib_name)) break;
}
if(!file_exists(lib_name))
@@ -2295,6 +2383,7 @@ bool
file_exists(const std::string& name)
{
struct stat buffer;
verbprintf(4, "querying whether file '%s' exists...\n", name.c_str());
return (stat(name.c_str(), &buffer) == 0);
}
@@ -2322,22 +2411,8 @@ using tim::dirname;
void
find_dyn_api_rt()
{
auto _exe_path = dirname(::get_realpath("/proc/self/exe"));
strvec_t _suffixes = {};
strvec_t _fallbacks = {};
if(strcmp(::basename(_exe_path.c_str()), "bin") == 0)
{
_suffixes.emplace_back("omnitrace");
_suffixes.emplace_back("../lib");
_suffixes.emplace_back("../lib/omnitrace");
_fallbacks.emplace_back(_exe_path);
}
else
{
_fallbacks.emplace_back(tim::get_env<std::string>("PWD", "."));
}
strvec_t _suffixes = libname_suffixes;
strvec_t _fallbacks = libname_fallbacks;
std::copy(_dyn_api_rt_paths.begin(), _dyn_api_rt_paths.end(),
std::back_inserter(_fallbacks));
+33
Просмотреть файл
@@ -27,6 +27,11 @@
#include "info.hpp"
#include "module_function.hpp"
#include <timemory/utility/filepath.hpp>
#include <string>
#include <sys/stat.h>
//======================================================================================//
inline string_t
@@ -153,6 +158,34 @@ private:
//
//======================================================================================//
//
static inline bool
omnitrace_get_is_executable(std::string_view _cmd, bool _default_v)
{
bool _is_executable = _default_v;
if(_cmd.empty())
{
if(!tim::filepath::exists(std::string{ _cmd }))
{
verbprintf(
0,
"Warning! '%s' was not found. Dyninst may fail to open the binary for "
"instrumentation...\n",
_cmd.data());
}
Dyninst::SymtabAPI::Symtab* _symtab = nullptr;
if(Dyninst::SymtabAPI::Symtab::openFile(_symtab, _cmd.data()))
{
_is_executable = _symtab->isExecutable() && _symtab->isExec();
Dyninst::SymtabAPI::Symtab::closeSymtab(_symtab);
}
}
return _is_executable;
}
//
//======================================================================================//
//
static inline address_space_t*
omnitrace_get_address_space(patch_pointer_t& _bpatch, int _cmdc, char** _cmdv,
bool _rewrite, int _pid = -1, const string_t& _name = {})
+79 -9
Просмотреть файл
@@ -2,12 +2,15 @@
function(OMNITRACE_ADD_BIN_TEST)
cmake_parse_arguments(
TEST
"" # options
"ADD_INVERSE" # options
"NAME;TARGET;TIMEOUT;WORKING_DIRECTORY" # single value args
"ARGS;ENVIRONMENT;LABELS;PROPERTIES;PASS_REGEX;FAIL_REGEX;SKIP_REGEX;DEPENDS;COMMAND" # multiple
# value args
${ARGN})
if(NOT TEST_WORKING_DIRECTORY)
set(TEST_WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
endif()
if(NOT OMNITRACE_DYNINST_API_RT_DIR AND OMNITRACE_DYNINST_API_RT)
get_filename_component(OMNITRACE_DYNINST_API_RT_DIR "${OMNITRACE_DYNINST_API_RT}"
DIRECTORY)
@@ -25,13 +28,19 @@ function(OMNITRACE_ADD_BIN_TEST)
"OMNITRACE_USE_TIMEMORY=ON"
"OMNITRACE_USE_SAMPLING=ON"
"OMNITRACE_TIME_OUTPUT=OFF"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
)
endif()
# common
list(APPEND TEST_ENVIRONMENT "OMNITRACE_CI=ON"
"OMNITRACE_OUTPUT_PATH=omnitrace-tests-output"
"OMNITRACE_OUTPUT_PREFIX=${TEST_NAME}/")
"OMNITRACE_OUTPUT_PATH=omnitrace-tests-output")
# copy for inverse
set(TEST_ENVIRONMENT_INV "${TEST_ENVIRONMENT}")
# different for regular test and inverse test
list(APPEND TEST_ENVIRONMENT "OMNITRACE_OUTPUT_PREFIX=${TEST_NAME}/")
list(APPEND TEST_ENVIRONMENT_INV "OMNITRACE_OUTPUT_PREFIX=${TEST_NAME}-inverse/")
if(TEST_COMMAND)
add_test(
@@ -56,11 +65,37 @@ function(OMNITRACE_ADD_BIN_TEST)
SKIP_REGULAR_EXPRESSION
"${TEST_SKIP_REGEX}"
${TEST_PROPERTIES})
if(TEST_ADD_INVERSE)
add_test(
NAME ${TEST_NAME}-inverse
COMMAND ${TEST_COMMAND} ${TEST_ARGS}
WORKING_DIRECTORY ${TEST_WORKING_DIRECTORY})
set_tests_properties(
${TEST_NAME}-inverse
PROPERTIES ENVIRONMENT
"${TEST_ENVIRONMENT_INV}"
TIMEOUT
${TEST_TIMEOUT}
DEPENDS
"${TEST_DEPENDS}"
LABELS
"omnitrace-bin;${TEST_LABELS}"
PASS_REGULAR_EXPRESSION
"${TEST_FAIL_REGEX}"
FAIL_REGULAR_EXPRESSION
"${TEST_PASS_REGEX}"
SKIP_REGULAR_EXPRESSION
"${TEST_SKIP_REGEX}"
WILL_FAIL
ON
${TEST_PROPERTIES})
endif()
elseif(TARGET ${TEST_TARGET})
add_test(
NAME ${TEST_NAME}
COMMAND $<TARGET_FILE:${TEST_TARGET}> ${TEST_ARGS}
WORKING_DIRECTORY $<TARGET_FILE_DIR:${TEST_TARGET}>)
WORKING_DIRECTORY ${TEST_WORKING_DIRECTORY})
set_tests_properties(
${TEST_NAME}
@@ -79,6 +114,32 @@ function(OMNITRACE_ADD_BIN_TEST)
SKIP_REGULAR_EXPRESSION
"${TEST_SKIP_REGEX}"
${TEST_PROPERTIES})
if(TEST_ADD_INVERSE)
add_test(
NAME ${TEST_NAME}-inverse
COMMAND $<TARGET_FILE:${TEST_TARGET}> ${TEST_ARGS}
WORKING_DIRECTORY ${TEST_WORKING_DIRECTORY})
set_tests_properties(
${TEST_NAME}-inverse
PROPERTIES ENVIRONMENT
"${TEST_ENVIRONMENT_INV}"
TIMEOUT
${TEST_TIMEOUT}
DEPENDS
"${TEST_DEPENDS}"
LABELS
"omnitrace-bin;${TEST_LABELS}"
PASS_REGULAR_EXPRESSION
"${TEST_FAIL_REGEX}"
FAIL_REGULAR_EXPRESSION
"${TEST_PASS_REGEX}"
SKIP_REGULAR_EXPRESSION
"${TEST_SKIP_REGEX}"
WILL_FAIL
ON
${TEST_PROPERTIES})
endif()
elseif(OMNITRACE_BUILD_TESTING)
message(FATAL_ERROR "Error! ${TEST_TARGET} does not exist")
endif()
@@ -103,7 +164,7 @@ omnitrace_add_bin_test(
txt
xml
-v
1
2
--all-functions
--
ls
@@ -113,14 +174,23 @@ omnitrace_add_bin_test(
omnitrace_add_bin_test(
NAME omnitrace-exe-simulate-ls-check
DEPENDS omnitrace-exe-simulate-ls
COMMAND ls
WORKING_DIRECTORY
${PROJECT_BINARY_DIR}/omnitrace-tests-output/omnitrace-exe-simulate-ls
COMMAND ls omnitrace-tests-output/omnitrace-exe-simulate-ls
TIMEOUT 60
PASS_REGEX
".*available-instr.json.*available-instr.txt.*available-instr.xml.*excluded-instr.json.*excluded-instr.txt.*excluded-instr.xml.*instrumented-instr.json.*instrumented-instr.txt.*instrumented-instr.xml.*overlapping-instr.json.*overlapping-instr.txt.*overlapping-instr.xml.*"
)
omnitrace_add_bin_test(
ADD_INVERSE
NAME omnitrace-exe-simulate-lib
TARGET omnitrace-exe
ARGS --print-available functions -v 2 -- $<TARGET_FILE:omnitrace-user-library>
LABELS "simulate"
TIMEOUT 120
PASS_REGEX
"\\\[omnitrace\\\]\\\[exe\\\] Runtime instrumentation is not possible!(.*)\n(.*)\\\[omnitrace\\\]\\\[exe\\\] Switching to binary rewrite mode and assuming '--simulate --all-functions'"
)
omnitrace_add_bin_test(
NAME omnitrace-avail-help
TARGET omnitrace-avail
+1 -1
Просмотреть файл
@@ -38,7 +38,7 @@ set_target_properties(
omnitrace-dl-library
PROPERTIES OUTPUT_NAME omnitrace-dl
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
BUILD_RPATH "\$ORIGIN"
INSTALL_RPATH "\$ORIGIN")
+1 -1
Просмотреть файл
@@ -26,7 +26,7 @@ set_target_properties(
omnitrace-user-library
PROPERTIES OUTPUT_NAME omnitrace-user
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
POSITION_INDEPENDENT_CODE ON
BUILD_RPATH "\$ORIGIN"
INSTALL_RPATH "\$ORIGIN")
+1 -1
Просмотреть файл
@@ -178,7 +178,7 @@ set_target_properties(
omnitrace-library
PROPERTIES OUTPUT_NAME omnitrace
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
INSTALL_RPATH "${OMNITRACE_LIB_INSTALL_RPATH}")
omnitrace_strip_target(omnitrace-library)
+7 -7
Просмотреть файл
@@ -32,7 +32,7 @@ set(_base_environment
"OMP_PROC_BIND=spread"
"OMP_PLACES=threads"
"OMP_NUM_THREADS=2"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
)
set(_lock_environment
@@ -45,7 +45,7 @@ set(_lock_environment
"OMNITRACE_TIME_OUTPUT=OFF"
"OMNITRACE_FLAT_PROFILE=ON"
"OMNITRACE_TIMELINE_PROFILE=OFF"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
)
set(_ompt_environment
@@ -57,7 +57,7 @@ set(_ompt_environment
"OMP_PROC_BIND=spread"
"OMP_PLACES=threads"
"OMP_NUM_THREADS=2"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
)
set(_perfetto_environment
@@ -69,7 +69,7 @@ set(_perfetto_environment
"OMP_PROC_BIND=spread"
"OMP_PLACES=threads"
"OMP_NUM_THREADS=2"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
)
set(_timemory_environment
@@ -81,7 +81,7 @@ set(_timemory_environment
"OMP_PROC_BIND=spread"
"OMP_PLACES=threads"
"OMP_NUM_THREADS=2"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
)
set(_test_environment ${_base_environment} "OMNITRACE_CRITICAL_TRACE=OFF")
@@ -95,7 +95,7 @@ set(_python_environment
"OMNITRACE_TREE_OUTPUT=OFF"
"OMNITRACE_USE_PID=OFF"
"OMNITRACE_TIMEMORY_COMPONENTS=trip_count"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
"PYTHONPATH=${PROJECT_BINARY_DIR}/lib/python/site-packages")
set(_attach_environment
@@ -111,7 +111,7 @@ set(_attach_environment
"OMP_PROC_BIND=spread"
"OMP_PLACES=threads"
"OMP_NUM_THREADS=2"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
)
# -------------------------------------------------------------------------------------- #