omnitrace -> omnitrace-instrument (#256)

* omnitrace-exe -> omnitrace-instrument

- Renamed omnitrace executable to omnitrace-instrument
- Provided dummy omnitrace exe which forwards onto omnitrace-instrument
- updated all docs to reflect the name change of the executable
  - however, it is possible some were missed

* Update dyninst submodule

- correctly handle BOOST_LINK_STATIC in DyninstBoost.cmake

* Disable IPO for omnitrace-instrument

[ROCm/rocprofiler-systems commit: ab0e5d9b44]
This commit is contained in:
Jonathan R. Madsen
2023-03-09 18:18:34 -06:00
committad av GitHub
förälder 81b67dcb88
incheckning 61a050fd1d
37 ändrade filer med 536 tillägg och 197 borttagningar
+5 -5
Visa fil
@@ -99,14 +99,14 @@ jobs:
ldd $(which omnitrace-critical-trace)
which omnitrace
ldd $(which omnitrace)
omnitrace --help
omnitrace -e -v 1 -o ls.inst --simulate -- ls
omnitrace-instrument --help
omnitrace-instrument -e -v 1 -o ls.inst --simulate -- ls
for i in $(find omnitrace-ls.inst-output -type f); do echo -e "\n\n --> ${i} \n\n"; cat ${i}; done
omnitrace -e -v 1 -o ls.inst -- ls
omnitrace-instrument -e -v 1 -o ls.inst -- ls
./ls.inst
omnitrace -e -v 1 --simulate -- ls
omnitrace-instrument -e -v 1 --simulate -- ls
for i in $(find omnitrace-ls-output -type f); do echo -e "\n\n --> ${i} \n\n"; cat ${i}; done
omnitrace -e -v 1 -- ls
omnitrace-instrument -e -v 1 -- ls
- name: Test User API
timeout-minutes: 10
+4 -4
Visa fil
@@ -40,7 +40,7 @@ jobs:
shell: bash
run:
echo "CC=$(echo '${{ matrix.compiler }}' | sed 's/+/c/g')" >> $GITHUB_ENV &&
echo "CXX=${{ matrix.compiler }}" >> $GITHUB_ENV &&
echo "CXX=${{ matrix.compiler }}" >> $GITHUB_ENV &&
env
- name: Install Packages
@@ -57,8 +57,8 @@ jobs:
if [ "${OS_VERSION_MAJOR}" -eq 8 ]; then PERL_REPO=powertools; else PERL_REPO=crb; fi && \
dnf -y --enablerepo=${PERL_REPO} install perl-File-BaseDir
yum install -y https://repo.radeon.com/amdgpu-install/${{ matrix.rocm-version }}/rhel/${{ matrix.os-release }}/amdgpu-install-${ROCM_MAJOR}.${ROCM_MINOR}.${ROCM_VERSN}-1${RPM_TAG}.noarch.rpm
amdgpu-install --usecase=rocm,hip,hiplibsdk --no-dkms --skip-broken -y
yum install -y rocm-hip-sdk rocm-smi-lib roctracer-dev rocprofiler-dev
amdgpu-install --usecase=rocm,hip,hiplibsdk --no-dkms --skip-broken -y
yum install -y rocm-hip-sdk rocm-smi-lib roctracer-dev rocprofiler-dev
- name: Configure, Build, and Test
timeout-minutes: 115
@@ -104,7 +104,7 @@ jobs:
run: |
set -v
source /opt/omnitrace/share/omnitrace/setup-env.sh
./scripts/test-install.sh --test-omnitrace{,-avail,-sample,-rewrite,-runtime,-critical-trace,-python}=1
./scripts/test-install.sh --test-omnitrace-{instrument,avail,sample,rewrite,runtime,critical-trace,python}=1
- name: Test User API
timeout-minutes: 10
@@ -130,14 +130,14 @@ jobs:
ldd $(which omnitrace-critical-trace)
which omnitrace
ldd $(which omnitrace)
omnitrace --help
omnitrace -e -v 1 -o ls.inst --simulate -- ls
omnitrace-instrument --help
omnitrace-instrument -e -v 1 -o ls.inst --simulate -- ls
for i in $(find omnitrace-ls.inst-output -type f); do echo -e "\n\n --> ${i} \n\n"; cat ${i}; done
omnitrace -e -v 1 -o ls.inst -- ls
omnitrace-instrument -e -v 1 -o ls.inst -- ls
./ls.inst
omnitrace -e -v 1 --simulate -- ls
omnitrace-instrument -e -v 1 --simulate -- ls
for i in $(find omnitrace-ls-output -type f); do echo -e "\n\n --> ${i} \n\n"; cat ${i}; done
omnitrace -e -v 1 -- ls
omnitrace-instrument -e -v 1 -- ls
- name: Test User API
timeout-minutes: 10
@@ -151,7 +151,7 @@ jobs:
module load omnitrace
echo $(which omnitrace)
ldd $(which omnitrace)
omnitrace --help
omnitrace-instrument --help
omnitrace-avail --help
omnitrace-sample --help
@@ -163,7 +163,7 @@ jobs:
source ./share/omnitrace/setup-env.sh
echo $(which omnitrace)
ldd $(which omnitrace)
omnitrace --help
omnitrace-instrument --help
omnitrace-avail --help
omnitrace-sample --help
@@ -180,7 +180,7 @@ jobs:
module use /opt/omnitrace/share/modulefiles
module avail
module load omnitrace
./scripts/test-install.sh --test-omnitrace{,-avail,-sample,-rewrite,-runtime,-critical-trace}=1 --test-omnitrace-python=${{ matrix.python }}
./scripts/test-install.sh --test-omnitrace-{instrument,avail,sample,rewrite,runtime,critical-trace}=1 --test-omnitrace-python=${{ matrix.python }}
- name: Test User API
timeout-minutes: 10
@@ -346,7 +346,7 @@ jobs:
shell: bash
run: |
source /opt/omnitrace/share/omnitrace/setup-env.sh
./scripts/test-install.sh --test-omnitrace{,-avail,-sample,-python,-rewrite,-runtime,-critical-trace}=1
./scripts/test-install.sh --test-omnitrace-{instrument,avail,sample,python,rewrite,runtime,critical-trace}=1
- name: Test User API
timeout-minutes: 10
@@ -504,7 +504,7 @@ jobs:
run: |
set -v
source /opt/omnitrace/share/omnitrace/setup-env.sh
${{ github.workspace }}/scripts/test-install.sh --test-omnitrace{,-avail,-sample,-python,-rewrite,-runtime,-critical-trace}=1
${{ github.workspace }}/scripts/test-install.sh --test-omnitrace-{instrument,avail,sample,python,rewrite,runtime,critical-trace}=1
- name: Test Install with Modulefile
timeout-minutes: 15
@@ -513,7 +513,7 @@ jobs:
source /usr/share/modules/init/$(basename ${SHELL})
module use /opt/omnitrace/share/modulefiles
module load omnitrace
${{ github.workspace }}/scripts/test-install.sh --test-omnitrace{,-avail,-sample,-python,-rewrite,-runtime,-critical-trace}=1
${{ github.workspace }}/scripts/test-install.sh --test-omnitrace-{instrument,avail,sample,python,rewrite,runtime,critical-trace}=1
- name: Test User API
timeout-minutes: 10
@@ -188,7 +188,7 @@ jobs:
module use /opt/omnitrace/share/modulefiles
module avail
module load omnitrace
./scripts/test-install.sh --test-omnitrace=1 --test-omnitrace-avail=1 --test-omnitrace-sample=1 --test-omnitrace-python=1 --test-omnitrace-rewrite=1 --test-omnitrace-runtime=1 --test-omnitrace-critical-trace=1
./scripts/test-install.sh --test-omnitrace-{instrument,avail,sample,python,rewrite,runtime,critical-trace}=1
- name: Test User API
timeout-minutes: 10
+11 -11
Visa fil
@@ -169,8 +169,8 @@ configuration variable to `ON`.
Similar to `omnitrace-sample`, use a double-hypen (`--`) to separate the command-line arguments for `omnitrace` from the target application and it's arguments.
```shell
omnitrace --help
omnitrace <omnitrace-options> -- <exe-or-library> <exe-options>
omnitrace-instrument --help
omnitrace-instrument <omnitrace-options> -- <exe-or-library> <exe-options>
```
#### Binary Rewrite
@@ -178,7 +178,7 @@ omnitrace <omnitrace-options> -- <exe-or-library> <exe-options>
Rewrite the text section of an executable or library with instrumentation:
```shell
omnitrace -o app.inst -- /path/to/app
omnitrace-instrument -o app.inst -- /path/to/app
```
In binary rewrite mode, if you also want instrumentation in the linked libraries, you must also rewrite those libraries.
@@ -186,7 +186,7 @@ Example of rewriting the functions starting with `"hip"` with instrumentation in
```shell
mkdir -p ./lib
omnitrace -R '^hip' -o ./lib/libamdhip64.so.4 -- /opt/rocm/lib/libamdhip64.so.4
omnitrace-instrument -R '^hip' -o ./lib/libamdhip64.so.4 -- /opt/rocm/lib/libamdhip64.so.4
export LD_LIBRARY_PATH=${PWD}/lib:${LD_LIBRARY_PATH}
```
@@ -206,7 +206,7 @@ is 1024000 KB (1 GiB):
```shell
# buffer size defaults to 1024000
omnitrace -o app.inst -- /path/to/app
omnitrace-instrument -o app.inst -- /path/to/app
./app.inst
```
@@ -214,7 +214,7 @@ Passing `--env OMNITRACE_PERFETTO_BUFFER_SIZE_KB=5120000` will change the defaul
```shell
# defaults to 5 GiB buffer size
omnitrace -o app.inst --env OMNITRACE_PERFETTO_BUFFER_SIZE_KB=5120000 -- /path/to/app
omnitrace-instrument -o app.inst --env OMNITRACE_PERFETTO_BUFFER_SIZE_KB=5120000 -- /path/to/app
./app.inst
```
@@ -231,9 +231,9 @@ linked libraries. Thus, it may be useful to exclude those libraries via the `-ME
or exclude specific functions with the `-E` regex option.
```shell
omnitrace -- /path/to/app
omnitrace -ME '^(libhsa-runtime64|libz\\.so)' -- /path/to/app
omnitrace -E 'rocr::atomic|rocr::core|rocr::HSA' -- /path/to/app
omnitrace-instrument -- /path/to/app
omnitrace-instrument -ME '^(libhsa-runtime64|libz\\.so)' -- /path/to/app
omnitrace-instrument -E 'rocr::atomic|rocr::core|rocr::HSA' -- /path/to/app
```
### Python Profiling and Tracing
@@ -328,12 +328,12 @@ export OMNITRACE_PERFETTO_BACKEND=system
And finally, execute your instrumented application. Either the binary rewritten application:
```shell
omnitrace -o ./myapp.inst -- ./myapp
omnitrace-instrument -o ./myapp.inst -- ./myapp
./myapp.inst
```
Or with runtime instrumentation:
```shell
omnitrace -- ./myapp
omnitrace-instrument -- ./myapp
```
Submodule projects/rocprofiler-systems/external/dyninst updated: dcc8dad3fb...d3ab0a71e9
@@ -36,7 +36,7 @@ fi
: ${CONFIG_DIR:=$(mktemp -t -d omnitrace-test-install-XXXX)}
: ${SOURCE_DIR:=$(dirname ${SCRIPT_DIR})}
: ${ENABLE_OMNITRACE:=1}
: ${ENABLE_OMNITRACE_INSTRUMENT:=1}
: ${ENABLE_OMNITRACE_AVAIL:=1}
: ${ENABLE_OMNITRACE_SAMPLE:=1}
: ${ENABLE_OMNITRACE_PYTHON:=0}
@@ -49,13 +49,13 @@ usage()
print_option() { printf " --%-10s %-24s %s (default: %s)\n" "${1}" "${2}" "${3}" "${4}"; }
echo "Options:"
print_option source-dir "<PATH>" "Location of source directory" "${SOURCE_DIR}"
print_option test-omnitrace "0|1" "Enable testing omnitrace exe" "${ENABLE_OMNITRACE}"
print_option test-omnitrace-instrument "0|1" "Enable testing omnitrace-instrument exe" "${ENABLE_OMNITRACE_INSTRUMENT}"
print_option test-omnitrace-avail "0|1" "Enable testing omnitrace-avail" "${ENABLE_OMNITRACE_AVAIL}"
print_option test-omnitrace-sample "0|1" "Enable testing omnitrace-sample" "${ENABLE_OMNITRACE_SAMPLE}"
print_option test-omnitrace-python "0|1" "Enable testing omnitrace-python" "${ENABLE_OMNITRACE_PYTHON}"
print_option test-omnitrace-rewrite "0|1" "Enable testing omnitrace binary rewrite" "${ENABLE_OMNITRACE_REWRITE}"
print_option test-omnitrace-runtime "0|1" "Enable testing omnitrace runtime instrumentation" "${ENABLE_OMNITRACE_RUNTIME}"
print_option test-omnitrace-critial-trace "0|1" "Enable testing omnitrace critical trace" "${ENABLE_OMNITRACE_CRITICAL_TRACE}"
print_option test-omnitrace-rewrite "0|1" "Enable testing omnitrace-instrument binary rewrite" "${ENABLE_OMNITRACE_REWRITE}"
print_option test-omnitrace-runtime "0|1" "Enable testing omnitrace-instrument runtime instrumentation" "${ENABLE_OMNITRACE_RUNTIME}"
print_option test-omnitrace-critial-trace "0|1" "Enable testing omnitrace-instrument critical trace" "${ENABLE_OMNITRACE_CRITICAL_TRACE}"
}
cat << EOF > ${CONFIG_DIR}/omnitrace.cfg
@@ -102,8 +102,8 @@ do
fi
case "${ARG}" in
--test-omnitrace)
ENABLE_OMNITRACE=${VAL}
--test-omnitrace-instrument)
ENABLE_OMNITRACE_INSTRUMENT=${VAL}
continue
;;
--test-omnitrace-avail)
@@ -146,7 +146,7 @@ test-omnitrace()
{
verbose-run which omnitrace
verbose-run ldd $(which omnitrace)
verbose-run omnitrace --help
verbose-run omnitrace-instrument --help
}
test-omnitrace-avail()
@@ -184,9 +184,9 @@ test-omnitrace-rewrite()
local LS_NAME=ls
local LS_ARGS=""
fi
verbose-run omnitrace -e -v 1 -o ${CONFIG_DIR}/ls.inst --simulate -- ${LS_NAME}
verbose-run omnitrace-instrument -e -v 1 -o ${CONFIG_DIR}/ls.inst --simulate -- ${LS_NAME}
for i in $(find ${CONFIG_DIR}/omnitrace-tests-output/ls.inst -type f); do verbose-run ls ${i}; done
verbose-run omnitrace -e -v 1 -o ${CONFIG_DIR}/ls.inst -- ${LS_NAME}
verbose-run omnitrace-instrument -e -v 1 -o ${CONFIG_DIR}/ls.inst -- ${LS_NAME}
verbose-run ${CONFIG_DIR}/ls.inst ${LS_ARGS}
}
@@ -199,9 +199,9 @@ test-omnitrace-runtime()
local LS_NAME=ls
local LS_ARGS=""
fi
verbose-run omnitrace -e -v 1 --simulate -- ${LS_NAME} ${LS_ARGS}
verbose-run omnitrace-instrument -e -v 1 --simulate -- ${LS_NAME} ${LS_ARGS}
for i in $(find ${CONFIG_DIR}/omnitrace-tests-output/$(basename ${LS_NAME}) -type f); do verbose-run ls ${i}; done
verbose-run omnitrace -e -v 1 -- ${LS_NAME} ${LS_ARGS}
verbose-run omnitrace-instrument -e -v 1 -- ${LS_NAME} ${LS_ARGS}
}
test-omnitrace-critical-trace()
@@ -210,7 +210,7 @@ test-omnitrace-critical-trace()
ldd $(which omnitrace-critical-trace)
}
if [ "${ENABLE_OMNITRACE}" -ne 0 ]; then verbose-run test-omnitrace; fi
if [ "${ENABLE_OMNITRACE_INSTRUMENT}" -ne 0 ]; then verbose-run test-omnitrace; fi
if [ "${ENABLE_OMNITRACE_AVAIL}" -ne 0 ]; then verbose-run test-omnitrace-avail; fi
if [ "${ENABLE_OMNITRACE_SAMPLE}" -ne 0 ]; then verbose-run test-omnitrace-sample; fi
if [ "${ENABLE_OMNITRACE_PYTHON}" -ne 0 ]; then verbose-run test-omnitrace-python; fi
@@ -96,7 +96,7 @@ setup-env()
test-install()
{
verbose-run omnitrace --help
verbose-run omnitrace-instrument --help
verbose-run omnitrace-avail --help
verbose-run omnitrace-avail --all
if [ -d "${1}/lib/python/site-packages/omnitrace" ]; then
@@ -18,7 +18,9 @@ add_subdirectory(omnitrace-avail)
add_subdirectory(omnitrace-critical-trace)
add_subdirectory(omnitrace-causal)
add_subdirectory(omnitrace-sample)
add_subdirectory(omnitrace)
add_subdirectory(omnitrace-instrument)
# omnitrace-exe is deprecated
add_subdirectory(omnitrace-exe)
if(OMNITRACE_BUILD_TESTING OR "$ENV{OMNITRACE_CI}" MATCHES "[1-9]+|ON|on|y|yes")
add_subdirectory(tests)
@@ -0,0 +1,23 @@
# ------------------------------------------------------------------------------#
#
# omnitrace-exe target (deprecated 'omnitrace' executable, now 'omnitrace-instrument')
#
# ------------------------------------------------------------------------------#
add_executable(omnitrace-exe ${CMAKE_CURRENT_LIST_DIR}/omnitrace.cpp)
target_link_libraries(omnitrace-exe PRIVATE omnitrace::omnitrace-threading)
set_target_properties(
omnitrace-exe
PROPERTIES OUTPUT_NAME omnitrace
BUILD_RPATH "\$ORIGIN:\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}"
INSTALL_RPATH "${OMNITRACE_EXE_INSTALL_RPATH}"
INSTALL_RPATH_USE_LINK_PATH ON)
omnitrace_strip_target(omnitrace-exe)
install(
TARGETS omnitrace-exe
DESTINATION ${CMAKE_INSTALL_BINDIR}
OPTIONAL)
@@ -0,0 +1,161 @@
// MIT License
//
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <future>
#include <iomanip>
#include <iostream>
#include <map>
#include <pthread.h>
#include <regex>
#include <signal.h>
#include <sstream>
#include <string_view>
#include <thread>
#include <unistd.h>
int
main(int argc, char** argv)
{
static const char* _warning = R"warning(
WWWWWWWW WWWWWWWW iiii !!!
W::::::W W::::::W i::::i !!:!!
W::::::W W::::::W iiii !:::!
W::::::W W::::::W !:::!
W:::::W WWWWW W:::::Waaaaaaaaaaaaa rrrrr rrrrrrrrr nnnn nnnnnnnn iiiiiiinnnn nnnnnnnn ggggggggg ggggg!:::!
W:::::W W:::::W W:::::W a::::::::::::a r::::rrr:::::::::r n:::nn::::::::nn i:::::in:::nn::::::::nn g:::::::::ggg::::g!:::!
W:::::W W:::::::W W:::::W aaaaaaaaa:::::ar:::::::::::::::::r n::::::::::::::nn i::::in::::::::::::::nn g:::::::::::::::::g!:::!
W:::::W W:::::::::W W:::::W a::::arr::::::rrrrr::::::rnn:::::::::::::::n i::::inn:::::::::::::::ng::::::ggggg::::::gg!:::!
W:::::W W:::::W:::::W W:::::W aaaaaaa:::::a r:::::r r:::::r n:::::nnnn:::::n i::::i n:::::nnnn:::::ng:::::g g:::::g !:::!
W:::::W W:::::W W:::::W W:::::W aa::::::::::::a r:::::r rrrrrrr n::::n n::::n i::::i n::::n n::::ng:::::g g:::::g !:::!
W:::::W:::::W W:::::W:::::W a::::aaaa::::::a r:::::r n::::n n::::n i::::i n::::n n::::ng:::::g g:::::g !!:!!
W:::::::::W W:::::::::W a::::a a:::::a r:::::r n::::n n::::n i::::i n::::n n::::ng::::::g g:::::g !!!
W:::::::W W:::::::W a::::a a:::::a r:::::r n::::n n::::ni::::::i n::::n n::::ng:::::::ggggg:::::g
W:::::W W:::::W a:::::aaaa::::::a r:::::r n::::n n::::ni::::::i n::::n n::::n g::::::::::::::::g !!!
W:::W W:::W a::::::::::aa:::ar:::::r n::::n n::::ni::::::i n::::n n::::n gg::::::::::::::g !!:!!
WWW WWW aaaaaaaaaa aaaarrrrrrr nnnnnn nnnnnniiiiiiii nnnnnn nnnnnn gggggggg::::::g !!!
g:::::g
gggggg g:::::g
g:::::gg gg:::::g
g::::::ggg:::::::g
gg:::::::::::::g
ggg::::::ggg
gggggg
OmniTrace has renamed the "omnitrace" executable to "omnitrace-instrument" to reduce confusion.
This executable only exists to provide this deprecation warning and maintain backwards compatibility for a few releases.
This executable will soon invoke "omnitrace-instrument" with the arguments you just provided after we've given you
a chance to read this message.
If you are running this job interactively, please acknowledge that you've read this message and whether you want to continue.
If you are running this job non-interactively, we will resume executing after ~1 minute unless CI or OMNITRACE_CI is defined
in the environment, in which case, we will throw an error.
Thanks for using OmniTrace and happy optimizing!
)warning";
auto _completed = std::promise<void>{};
bool _acknowledged = false;
auto _emit_warning = []() {
// emit warning
std::cerr << _warning << std::endl;
};
auto _get_env = [](const char* _var) {
auto* _val = getenv(_var);
if(_val == nullptr) return false;
return !std::regex_match(
_val, std::regex{ "0|false|off|no", std::regex_constants::icase });
};
auto _env_failure = [_emit_warning, argv](std::string_view _env_var) {
// emit warning
_emit_warning();
std::cerr << "[" << argv[0] << "] Detected " << _env_var
<< " environment variable. Exiting to prevent consuming CI resources. "
"Use \"omnitrace-instrument\" executable instead of \"omnitrace\" "
"to prevent this error."
<< std::endl;
std::exit(EXIT_FAILURE);
};
auto _wait_for_input = [&_completed, &_acknowledged, _emit_warning]() {
// emit warning and wait for input
_emit_warning();
std::cerr << "Do you want to continue? [Y/n] " << std::flush;
auto _input = char{};
std::cin.get(_input);
_input = tolower(_input);
if(_input == 'n') std::exit(EXIT_SUCCESS);
_acknowledged = true;
_completed.set_value();
};
for(const auto* itr : { "CI", "OMNITRACE_CI" })
{
if(_get_env(itr)) _env_failure(itr);
}
{
auto _thr = std::thread{ _wait_for_input };
_completed.get_future().wait_for(std::chrono::seconds{ 60 });
if(!_acknowledged)
{
std::cerr << "[" << argv[0]
<< "] No acknowledgement after 1 minute. Continuing..."
<< std::endl;
_thr.detach();
}
else
_thr.join();
}
// generate the new command
auto _argv = std::vector<char*>{};
_argv.emplace_back(
strdup(std::string{ std::string{ argv[0] } + "-instrument" }.c_str()));
for(int i = 1; i < argc; ++i)
_argv.emplace_back(argv[i]);
// echo the new command for diagnostic purposes
auto _cmdss = std::stringstream{};
for(const auto& itr : _argv)
if(itr) _cmdss << " " << itr;
auto _cmd = _cmdss.str();
if(!_cmd.empty())
std::cerr << "[" << argv[0] << "] Executing: \"" << _cmd.substr(1) << "\"...\n"
<< std::endl;
// make sure command ends with nullptr
_argv.emplace_back(nullptr);
return execvp(_argv.front(), _argv.data());
}
@@ -1,15 +1,15 @@
# ------------------------------------------------------------------------------#
#
# omnitrace-exe target
# omnitrace-instrument target (formerly omnitrace-exe target prior to 1.8.1)
#
# ------------------------------------------------------------------------------#
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF)
add_executable(omnitrace-exe)
add_executable(omnitrace-instrument)
target_sources(
omnitrace-exe
omnitrace-instrument
PRIVATE ${CMAKE_CURRENT_LIST_DIR}/details.cpp
${CMAKE_CURRENT_LIST_DIR}/function_signature.cpp
${CMAKE_CURRENT_LIST_DIR}/function_signature.hpp
@@ -21,11 +21,11 @@ target_sources(
${CMAKE_CURRENT_LIST_DIR}/log.hpp
${CMAKE_CURRENT_LIST_DIR}/module_function.cpp
${CMAKE_CURRENT_LIST_DIR}/module_function.hpp
${CMAKE_CURRENT_LIST_DIR}/omnitrace.cpp
${CMAKE_CURRENT_LIST_DIR}/omnitrace.hpp)
${CMAKE_CURRENT_LIST_DIR}/omnitrace-instrument.cpp
${CMAKE_CURRENT_LIST_DIR}/omnitrace-instrument.hpp)
target_link_libraries(
omnitrace-exe
omnitrace-instrument
PRIVATE omnitrace::omnitrace-headers
omnitrace::omnitrace-dyninst
omnitrace::omnitrace-compile-options
@@ -36,24 +36,23 @@ target_link_libraries(
timemory::timemory-core)
set_target_properties(
omnitrace-exe
PROPERTIES OUTPUT_NAME omnitrace
BUILD_RPATH "\$ORIGIN:\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}"
omnitrace-instrument
PROPERTIES BUILD_RPATH "\$ORIGIN:\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}"
INSTALL_RPATH "${OMNITRACE_EXE_INSTALL_RPATH}"
INSTALL_RPATH_USE_LINK_PATH ON)
if(OMNITRACE_BUILD_DYNINST)
target_compile_definitions(omnitrace-exe PRIVATE OMNITRACE_BUILD_DYNINST=1)
target_compile_definitions(omnitrace-instrument PRIVATE OMNITRACE_BUILD_DYNINST=1)
endif()
omnitrace_strip_target(omnitrace-exe)
omnitrace_strip_target(omnitrace-instrument)
if(CMAKE_BUILD_TYPE MATCHES "^(DEBUG|Debug)")
string(REPLACE " " ";" _FLAGS "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
target_compile_options(omnitrace-exe PRIVATE ${_FLAGS})
target_compile_options(omnitrace-instrument PRIVATE ${_FLAGS})
endif()
install(
TARGETS omnitrace-exe
TARGETS omnitrace-instrument
DESTINATION ${CMAKE_INSTALL_BINDIR}
OPTIONAL)
@@ -23,7 +23,7 @@
#include "function_signature.hpp"
#include "fwd.hpp"
#include "log.hpp"
#include "omnitrace.hpp"
#include "omnitrace-instrument.hpp"
#include <timemory/components/rusage/components.hpp>
#include <timemory/components/timing/wall_clock.hpp>
@@ -25,7 +25,7 @@
#include "fwd.hpp"
#include "internal_libs.hpp"
#include "log.hpp"
#include "omnitrace.hpp"
#include "omnitrace-instrument.hpp"
#include <timemory/utility/join.hpp>
@@ -20,7 +20,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include "omnitrace.hpp"
#include "omnitrace-instrument.hpp"
#include "common/defines.h"
#include "fwd.hpp"
#include "internal_libs.hpp"
@@ -453,7 +453,7 @@ main(int argc, char** argv)
// it is unrecognized, then set the errflag to report an error. When we come to a
// non '-' charcter, then we must be at the application name.
using parser_t = tim::argparse::argument_parser;
parser_t parser("omnitrace");
parser_t parser("omnitrace-instrument");
string_t extra_help = "-- <CMD> <ARGS>";
parser.enable_help();
@@ -147,13 +147,13 @@ function(OMNITRACE_ADD_BIN_TEST)
endfunction()
omnitrace_add_bin_test(
NAME omnitrace-exe-help
TARGET omnitrace-exe
NAME omnitrace-instrument-help
TARGET omnitrace-instrument
ARGS --help
LABELS omnitrace-exe
LABELS omnitrace-instrument
TIMEOUT 45
PASS_REGEX
".*\\\[omnitrace\\\] Usage:.*\\\[DEBUG OPTIONS\\\].*\\\[MODE OPTIONS\\\].*\\\[LIBRARY OPTIONS\\\].*\\\[SYMBOL SELECTION OPTIONS\\\].*\\\[RUNTIME OPTIONS\\\].*\\\[GRANULARITY OPTIONS\\\].*\\\[DYNINST OPTIONS\\\].*"
".*\\\[omnitrace-instrument\\\] Usage:.*\\\[DEBUG OPTIONS\\\].*\\\[MODE OPTIONS\\\].*\\\[LIBRARY OPTIONS\\\].*\\\[SYMBOL SELECTION OPTIONS\\\].*\\\[RUNTIME OPTIONS\\\].*\\\[GRANULARITY OPTIONS\\\].*\\\[DYNINST OPTIONS\\\].*"
)
# on RedHat, /usr/bin/ls is a script for `coreutils --coreutils-prog=ls`
@@ -166,8 +166,8 @@ else()
endif()
omnitrace_add_bin_test(
NAME omnitrace-exe-simulate-ls
TARGET omnitrace-exe
NAME omnitrace-instrument-simulate-ls
TARGET omnitrace-instrument
ARGS --simulate
--print-format
json
@@ -183,9 +183,9 @@ omnitrace_add_bin_test(
TIMEOUT 240)
omnitrace_add_bin_test(
NAME omnitrace-exe-simulate-ls-check
DEPENDS omnitrace-exe-simulate-ls
COMMAND ls omnitrace-tests-output/omnitrace-exe-simulate-ls/instrumentation
NAME omnitrace-instrument-simulate-ls-check
DEPENDS omnitrace-instrument-simulate-ls
COMMAND ls omnitrace-tests-output/omnitrace-instrument-simulate-ls/instrumentation
TIMEOUT 60
PASS_REGEX
".*available.json.*available.txt.*available.xml.*excluded.json.*excluded.txt.*excluded.xml.*instrumented.json.*instrumented.txt.*instrumented.xml.*overlapping.json.*overlapping.txt.*overlapping.xml.*"
@@ -193,8 +193,8 @@ omnitrace_add_bin_test(
omnitrace_add_bin_test(
ADD_INVERSE
NAME omnitrace-exe-simulate-lib
TARGET omnitrace-exe
NAME omnitrace-instrument-simulate-lib
TARGET omnitrace-instrument
ARGS --print-available functions -v 2 -- $<TARGET_FILE:omnitrace-user-library>
LABELS "simulate"
TIMEOUT 120
@@ -205,14 +205,14 @@ omnitrace_add_bin_test(
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/omnitrace-tests-output/tmp)
omnitrace_add_bin_test(
NAME omnitrace-exe-simulate-lib-basename
TARGET omnitrace-exe
NAME omnitrace-instrument-simulate-lib-basename
TARGET omnitrace-instrument
ARGS --print-available
functions
-v
2
-o
${PROJECT_BINARY_DIR}/omnitrace-tests-output/omnitrace-exe-simulate-lib-basename/${CMAKE_SHARED_LIBRARY_PREFIX}$<TARGET_FILE_BASE_NAME:omnitrace-user-library>${CMAKE_SHARED_LIBRARY_SUFFIX}
${PROJECT_BINARY_DIR}/omnitrace-tests-output/omnitrace-instrument-simulate-lib-basename/${CMAKE_SHARED_LIBRARY_PREFIX}$<TARGET_FILE_BASE_NAME:omnitrace-user-library>${CMAKE_SHARED_LIBRARY_SUFFIX}
--
${CMAKE_SHARED_LIBRARY_PREFIX}$<TARGET_FILE_BASE_NAME:omnitrace-user-library>${CMAKE_SHARED_LIBRARY_SUFFIX}
LABELS "simulate"
@@ -220,8 +220,8 @@ omnitrace_add_bin_test(
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/omnitrace-tests-output/tmp)
omnitrace_add_bin_test(
NAME omnitrace-exe-write-log
TARGET omnitrace-exe
NAME omnitrace-instrument-write-log
TARGET omnitrace-instrument
ARGS --print-instrumented
functions
-v
@@ -236,9 +236,10 @@ omnitrace_add_bin_test(
PASS_REGEX "Opening .*/instrumentation/user.log")
omnitrace_add_bin_test(
NAME omnitrace-exe-write-log-check
DEPENDS omnitrace-exe-write-log
COMMAND ls omnitrace-tests-output/omnitrace-exe-write-log/instrumentation/user.log
NAME omnitrace-instrument-write-log-check
DEPENDS omnitrace-instrument-write-log
COMMAND ls
omnitrace-tests-output/omnitrace-instrument-write-log/instrumentation/user.log
LABELS "log"
TIMEOUT 60
PASS_REGEX "user.log"
@@ -36,9 +36,9 @@ for each variant:
- child process launches `<command> <command-args>` via `execvpe` which modified environment for variant
- parent process waits for child process to finish
### omnitrace: [source/bin/omnitrace](https://github.com/AMDResearch/omnitrace/tree/main/source/bin/omnitrace)
### omnitrace-instrument: [source/bin/omnitrace-instrument](https://github.com/AMDResearch/omnitrace/tree/main/source/bin/omnitrace-instrument)
- Requires a command-line format of `omnitrace <options> -- <command> <command-args>`
- Requires a command-line format of `omnitrace-instrument <options> -- <command> <command-args>`
- User specifies in options whether they want to do runtime instrumentation, binary rewrite, or attach to process
- Either opens the instrumentation target (binary rewrite), launches the target and stops it before it starts executing main (runtime), or
attaches to running executable and pauses it
@@ -294,7 +294,7 @@ The last component [backtrace_metrics](https://github.com/AMDResearch/omnitrace/
metrics for that sample, e.g. peak RSS, HW counters, etc. These 3 components are bundled together in a tuple-like struct (e.g. `tuple<backtrace_timestamp, backtrace, backtrace_metrics>`)
a buffer of at least 1024 instances of this tuple are mmap'ed per-thread. When this buffer is full, before taking the next sample, the sampler will hand the buffer
off to it's allocator thread and mmap a new buffer. The allocator thread takes this data and either dynamically stores it in memory or writes it to a file depending on the value of `OMNITRACE_USE_TEMPORARY_FILES`.
This schema avoids all allocations in the signal handler, allows the data to grow dynamically, avoid potentially slow I/O within the signal handler, and also enables the capability to avoid I/O altogether.
This schema avoids all allocations in the signal handler, allows the data to grow dynamically, avoid potentially slow I/O within the signal handler, and also enables the capability to avoid I/O altogether.
The maximum number of samplers handled by each allocator is governed by the setting `OMNITRACE_SAMPLING_ALLOCATOR_SIZE` setting (the default is 8) -- whenever an allocator has reached it's limit,
a new internal thread is created to handle the new samplers.
@@ -64,11 +64,11 @@ e.g., omnitrace's meaning of the term "module" when instrumenting Python.
- **Instrumentation Traps**
- On the x86 architecture, because instructions are of variable size, the instruction at a point may be too small for Dyninst to replace it with the normal code sequence used to call instrumentation
- Also, when instrumentation is placed at points other than subroutine entry, exit, or call points, traps may be used to ensure the instrumentation fits
- By default, omnitrace avoids instrumentation which requires using a trap
- By default, omnitrace-instrument avoids instrumentation which requires using a trap
- **Overlapping functions**
- Due to language constructs or compiler optimizations, it may be possible for multiple functions to overlap (that is, share part of the same function body) or for a single function to have multiple entry points
- In practice, it is impossible to determine the difference between multiple overlapping functions and a single function with multiple entry points
- By default, omnitrace avoids instrumenting overlapping functions
- By default, omnitrace-instrument avoids instrumenting overlapping functions
## General Tips
@@ -173,7 +173,7 @@ such as `fib`, will result in *significant* overhead since this simple function
exit snippets are ~1024 instructions. Thus, ***we generally want to avoid instrumenting functions where the instrumented function has significantly fewer
instructions than entry + exit instrumentation*** (please note, however, that many of the instructions entry/exit functions are either logging functions or
depend on the runtime settins and thus may never be executed). However, due to the number of potentially executed instructions in the entry/exit snippets,
the default behavior of omnitrace is to only instrument functions which contain fewer than 1024 instructions.
the default behavior of omnitrace-instrument is to only instrument functions which contain fewer than 1024 instructions.
However, recording every single invocation of the function can be extremely useful for detecting anomalies: profiles will show min/max values much smaller/larger
than the average and/or high standard deviation and traces will allow you to identify exactly when and where those instances deviated from the norm.
@@ -35,8 +35,11 @@ The relevent fields are `ID` and the `VERSION_ID`.
## Architecture
At present, only amd64 (x86_64) architectures are tested but Dyninst supports several more architectures.
Thus, omnitrace should support other CPU architectures such as aarch64, ppc64, etc.
With regards to instrumentation, at present only amd64 (x86_64) architectures are tested; however,
Dyninst supports several more architectures and thus, omnitrace instrumentation may support other
CPU architectures such as aarch64, ppc64, etc.
Other modes of use, such as sampling and causal profiling, are not dependent on Dyninst and therefore
may be more portable.
## Installing omnitrace from binary distributions
@@ -244,7 +247,7 @@ source /opt/omnitrace/share/omnitrace/setup-env.sh
Successful execution of these commands indicates that the installation does not have any issues locating the installed libraries:
```shell
omnitrace --help
omnitrace-instrument --help
omnitrace-avail --help
```
@@ -6,103 +6,138 @@
:maxdepth: 4
```
## omnitrace Executable
## omnitrace-instrument Executable
> ***NOTE: With the introduction of `omnitrace-sample`, in future versions of omnitrace, the current `omnitrace` executable***
> ***noted below will likely be renamed to `omnitrace-instrument` and a new `omnitrace` executable will serve as a common***
> ***executable for multiple executables, e.g. `omnitrace sample ...`, `omnitrace run ...`, `omnitrace rewrite ...`, etc.***
> ***executable for multiple executables, e.g. `omnitrace-instrument sample ...`, `omnitrace run ...`, `omnitrace rewrite ...`, etc.***
Instrumentation is performed with the `omnitrace` executable. View the help menu with the `-h` / `--help` option:
```console
$ omnitrace --help
[omnitrace] Usage: omnitrace [ --help (count: 0, dtype: bool)
--debug (max: 1, dtype: bool)
--verbose (max: 1, dtype: bool)
--error (max: 1, dtype: boolean)
--simulate (max: 1, dtype: bool)
--print-format (min: 1, dtype: string)
--print-dir (count: 1, dtype: string)
--print-available (count: 1)
--print-instrumented (count: 1)
--print-excluded (count: 1)
--print-overlapping (count: 1)
--output (count: 1)
--pid (count: 1, dtype: int)
--mode (count: 1)
--command (count: 1)
--prefer (count: 1)
--library (count: unlimited)
--main-function (count: 1)
--driver (max: 1, dtype: boolean)
--load (count: unlimited, dtype: string)
--load-instr (count: unlimited, dtype: filepath)
--init-functions (count: unlimited, dtype: string)
--fini-functions (count: unlimited, dtype: string)
--function-include (count: unlimited)
--function-exclude (count: unlimited)
--module-include (count: unlimited)
--module-exclude (count: unlimited)
--label (count: unlimited, dtype: string)
--default-components (count: unlimited, dtype: string)
--env (count: unlimited)
--mpi (max: 1, dtype: bool)
--instrument-loops (max: 1, dtype: boolean)
--min-address-range (count: 1, dtype: int)
--min-address-range-loop (count: 1, dtype: int)
--dynamic-callsites (max: 1, dtype: boolean)
--traps (max: 1, dtype: bool)
--loop-traps (max: 1, dtype: bool)
--allow-overlapping (count: 0, dtype: bool)
--batch-size (count: 1, dtype: int)
--dyninst-options (count: unlimited)
] -- <CMD> <ARGS>
$ omnitrace-instrument --help
[omnitrace-instrument] Usage: omnitrace-instrument [ --help (count: 0, dtype: bool)
--version (count: 0, dtype: bool)
--verbose (max: 1, dtype: bool)
--error (max: 1, dtype: boolean)
--debug (max: 1, dtype: bool)
--log (count: 1)
--log-file (count: 1)
--simulate (max: 1, dtype: boolean)
--print-format (min: 1, dtype: string)
--print-dir (count: 1, dtype: string)
--print-available (count: 1)
--print-instrumented (count: 1)
--print-coverage (count: 1)
--print-excluded (count: 1)
--print-overlapping (count: 1)
--print-instructions (max: 1, dtype: bool)
--output (min: 0, dtype: string)
--pid (count: 1, dtype: int)
--mode (count: 1)
--force (max: 1, dtype: bool)
--command (count: 1)
--prefer (count: 1)
--library (count: unlimited)
--main-function (count: 1)
--load (count: unlimited, dtype: string)
--load-instr (count: unlimited, dtype: filepath)
--init-functions (count: unlimited, dtype: string)
--fini-functions (count: unlimited, dtype: string)
--all-functions (max: 1, dtype: boolean)
--function-include (count: unlimited)
--function-exclude (count: unlimited)
--function-restrict (count: unlimited)
--caller-include (count: unlimited)
--module-include (count: unlimited)
--module-exclude (count: unlimited)
--module-restrict (count: unlimited)
--internal-function-include (count: unlimited)
--internal-module-include (count: unlimited)
--instruction-exclude (count: unlimited)
--internal-library-deps (min: 0, dtype: boolean)
--internal-library-append (count: unlimited)
--internal-library-remove (count: unlimited)
--linkage (min: 1)
--visibility (min: 1)
--label (count: unlimited, dtype: string)
--config (min: 1, dtype: string)
--default-components (count: unlimited, dtype: string)
--env (count: unlimited)
--mpi (max: 1, dtype: bool)
--instrument-loops (max: 1, dtype: boolean)
--min-instructions (count: 1, dtype: int)
--min-address-range (count: 1, dtype: int)
--min-instructions-loop (count: 1, dtype: int)
--min-address-range-loop (count: 1, dtype: int)
--coverage (max: 1, dtype: bool)
--dynamic-callsites (max: 1, dtype: boolean)
--traps (max: 1, dtype: boolean)
--loop-traps (max: 1, dtype: boolean)
--allow-overlapping (max: 1, dtype: bool)
--parse-all-modules (max: 1, dtype: bool)
--batch-size (count: 1, dtype: int)
--dyninst-rt (min: 1, dtype: filepath)
--dyninst-options (count: unlimited)
] -- <CMD> <ARGS>
Options:
-h, -?, --help Shows this page
--version Prints the version and exit
[DEBUG OPTIONS]
--debug Debug output
-v, --verbose Verbose output
-e, --error All warnings produce runtime errors
--debug Debug output
--log Number of log entries to display after an error. Any value < 0 will emit the entire log
--log-file Write the log out the specified file during the run
--simulate Exit after outputting diagnostic {available,instrumented,excluded,overlapping} module
function lists, e.g. available-instr.txt
function lists, e.g. available.txt
--print-format [ json | txt | xml ]
Output format for diagnostic {available,instrumented,excluded,overlapping} module
function lists, e.g. {print-dir}/available-instr.txt
function lists, e.g. {print-dir}/available.txt
--print-dir Output directory for diagnostic {available,instrumented,excluded,overlapping} module
function lists, e.g. {print-dir}/available-instr.txt
function lists, e.g. {print-dir}/available.txt
--print-available [ functions | functions+ | modules | pair | pair+ ]
Print the available entities for instrumentation (functions, modules, or module-function
pair) to stdout applying regular expressions and exit
pair) to stdout after applying regular expressions
--print-instrumented [ functions | functions+ | modules | pair | pair+ ]
Print the instrumented entities (functions, modules, or module-function pair) to stdout
after applying regular expressions and exit
after applying regular expressions
--print-coverage [ functions | functions+ | modules | pair | pair+ ]
Print the instrumented coverage entities (functions, modules, or module-function pair) to
stdout after applying regular expressions
--print-excluded [ functions | functions+ | modules | pair | pair+ ]
Print the entities for instrumentation (functions, modules, or module-function pair)
which are excluded from the instrumentation to stdout after applying regular expressions
and exit
--print-overlapping [ functions | functions+ | modules | pair | pair+ ]
Print the entities for instrumentation (functions, modules, or module-function pair)
which overlap other function calls or have multiple entry points to stdout applying
regular expressions and exit
which overlap other function calls or have multiple entry points to stdout after applying
regular expressions
--print-instructions Print the instructions for each basic-block in the JSON/XML outputs
[MODE OPTIONS]
-o, --output Enable generation of a new executable (binary-rewrite)
-o, --output Enable generation of a new executable (binary-rewrite). If a filename is not provided,
omnitrace will use the basename and output to the cwd, unless the target binary is in the
cwd. In the latter case, omnitrace will either use ${PWD}/<basename>.inst (non-libraries)
or ${PWD}/instrumented/<basename> (libraries)
-p, --pid Connect to running process
-M, --mode [ sampling | trace ]
-M, --mode [ coverage | sampling | trace ]
Instrumentation mode. 'trace' mode instruments the selected functions, 'sampling' mode
only instruments the main function to start and stop the sampler.
-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')
-c, --command Input executable and arguments (if '-- <CMD>' not provided)
[LIBRARY OPTIONS]
--prefer [ shared | static ] Prefer this library types when available
-L, --library Libraries with instrumentation routines (default: "libomnitrace")
-L, --library Libraries with instrumentation routines (default: "libomnitrace-dl")
-m, --main-function The primary function to instrument around, e.g. 'main'
--driver Force main or _init/_fini instrumentation
--load Supplemental instrumentation library names w/o extension (e.g. 'libinstr' for
'libinstr.so' or 'libinstr.a')
--load-instr Load {available,instrumented,excluded,overlapping}-instr JSON or XML file(s) and override
@@ -110,13 +145,99 @@ Options:
--init-functions Initialization function(s) for supplemental instrumentation libraries (see '--load'
option)
--fini-functions Finalization function(s) for supplemental instrumentation libraries (see '--load' option)
--all-functions When finding functions, include the functions which are not instrumentable. This is
purely diagnostic for the available/excluded functions output
[SYMBOL SELECTION OPTIONS]
-I, -R, --function-include Regex for selecting functions
-E, --function-exclude Regex for excluding functions
-MI, -MR, --module-include Regex for selecting modules/files/libraries
-ME, --module-exclude Regex for excluding modules/files/libraries
-I, --function-include Regex(es) for including functions (despite heuristics)
-E, --function-exclude Regex(es) for excluding functions (always applied)
-R, --function-restrict Regex(es) for restricting functions only to those that match the provided
regular-expressions
--caller-include Regex(es) for including functions that call the listed functions (despite heuristics)
-MI, --module-include Regex(es) for selecting modules/files/libraries (despite heuristics)
-ME, --module-exclude Regex(es) for excluding modules/files/libraries (always applied)
-MR, --module-restrict Regex(es) for restricting modules/files/libraries only to those that match the provided
regular-expressions
--internal-function-include Regex(es) for including functions which are (likely) utilized by omnitrace itself. Use
this option with care.
--internal-module-include Regex(es) for including modules/libraries which are (likely) utilized by omnitrace
itself. Use this option with care.
--instruction-exclude Regex(es) for excluding functions containing certain instructions
--internal-library-deps Treat the libraries linked to the internal libraries as internal libraries. This increase
the internal library processing time and consume more memory (so use with care) but may
be useful when the application uses Boost libraries and Dyninst is dynamically linked
against the same boost libraries
--internal-library-append Append to the list of libraries which omnitrace treats as being used internally, e.g.
OmniTrace will find all the symbols in this library and prevent them from being
instrumented.
--internal-library-remove [ ld-linux-x86-64.so.2
libBrokenLocale.so.1
libanl.so.1
libbfd.so
libbz2.so
libc.so.6
libcaliper.so
libcommon.so
libcrypt.so.1
libdl.so.2
libdw.so
libdwarf.so
libdyninstAPI_RT.so
libelf.so
libgcc_s.so.1
libgotcha.so
liblikwid.so
liblzma.so
libnsl.so.1
libnss_compat.so.2
libnss_db.so.2
libnss_dns.so.2
libnss_files.so.2
libnss_hesiod.so.2
libnss_ldap.so.2
libnss_nis.so.2
libnss_nisplus.so.2
libnss_test1.so.2
libnss_test2.so.2
libpapi.so
libpfm.so
libprofiler.so
libpthread.so.0
libresolv.so.2
librocm_smi64.so
librocmtools.so
librocprofiler64.so
libroctracer64.so
libroctx64.so
librt.so.1
libstdc++.so.6
libtbb.so
libtbbmalloc.so
libtbbmalloc_proxy.so
libtcmalloc.so
libtcmalloc_and_profiler.so
libtcmalloc_debug.so
libtcmalloc_minimal.so
libtcmalloc_minimal_debug.so
libthread_db.so.1
libunwind-coredump.so
libunwind-generic.so
libunwind-ptrace.so
libunwind-setjmp.so
libunwind-x86_64.so
libunwind.so
libutil.so.1
libz.so
libzstd.so ]
Remove the specified libraries from being treated as being used internally, e.g.
OmniTrace will permit all the symbols in these libraries to be eligible for
instrumentation.
--linkage [ global | local | unique | unknown | weak ]
Only instrument functions with specified linkage (default: global, local, unique)
--visibility [ default | hidden | internal | protected | unknown ]
Only instrument functions with specified visibility (default: default, internal, hidden,
protected)
[RUNTIME OPTIONS]
@@ -124,21 +245,30 @@ Options:
Labeling info for functions. By default, just the function name is recorded. Use these
options to gain more information about the function signature or location of the
functions
-C, --config Read in a configuration file and encode these values as the defaults in the executable
-d, --default-components Default components to instrument (only useful when timemory is enabled in omnitrace
library)
--env Environment variables to add to the runtime in form VARIABLE=VALUE. E.g. use '--env
OMNITRACE_USE_TIMEMORY=ON' to default to using timemory instead of perfetto
--mpi Enable MPI support (requires omnitrace built w/ MPI and GOTCHA support). NOTE: this will
automatically be activated if MPI_Init/MPI_Init_thread and MPI_Finalize are found in the
symbol table of target
--mpi Enable MPI support (requires omnitrace built w/ full or partial MPI support). NOTE: this
will automatically be activated if MPI_Init, MPI_Init_thread, MPI_Finalize,
MPI_Comm_rank, or MPI_Comm_size are found in the symbol table of target
[GRANULARITY OPTIONS]
-l, --instrument-loops Instrument at the loop level
-i, --min-instructions If the number of instructions in a function is less than this value, exclude it from
instrumentation
-r, --min-address-range If the address range of a function is less than this value, exclude it from
instrumentation
--min-instructions-loop If the number of instructions in a function containing a loop is less than this value,
exclude it from instrumentation
--min-address-range-loop If the address range of a function containing a loop is less than this value, exclude it
from instrumentation
--coverage [ basic_block | function | none ]
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).
--dynamic-callsites Force instrumentation if a function has dynamic callsites (e.g. function pointers)
--traps Instrument points which require using a trap. On the x86 architecture, because
instructions are of variable size, the instruction at a point may be too small for
@@ -151,19 +281,32 @@ Options:
--allow-overlapping 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.
--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
[DYNINST OPTIONS]
-b, --batch-size Dyninst supports batch insertion of multiple points during runtime instrumentation. If
one large batch insertion fails, this value will be used to create smaller batches.
Larger batches generally decrease the instrumentation time
--dyninst-options [ BaseTrampDeletion | DebugParsing | DelayedParsing | InstrStackFrames | MergeTramp | SaveFPR | TrampRecursive | TypeChecking ]
--dyninst-rt Path(s) to the dyninstAPI_RT library
--dyninst-options [ BaseTrampDeletion
DebugParsing
DelayedParsing
InstrStackFrames
MergeTramp
SaveFPR
TrampRecursive
TypeChecking ]
Advanced dyninst options: BPatch::set<OPTION>(bool), e.g. bpatch->setTrampRecursive(true)
```
There are three ways to perform instrumentation:
1. Running the application via the omnitrace executable (analagous to `gdb --args <program> <args>`)
1. Running the application via the omnitrace-instrument executable (analagous to `gdb --args <program> <args>`)
- This mode is the default if neither the `-p` nor `-o` comand-line options are used
- Runtime instrumentation supports instrumenting not only the target executable but also the
the shared libraries loaded by the target executable. Consequently, this mode consumes more memory,
@@ -187,29 +330,29 @@ There are three ways to perform instrumentation:
> ***Attaching to a running process is an alpha feature and support for detaching from the target process***
> ***without ending the target process is not currently supported.***
The general syntax for separating omnitrace command line arguments from the application arguments follows the
The general syntax for separating omnitrace command line arguments from the application arguments
is consistent with the LLVM style of using a standalone double-hyphen (`--`). All arguments preceding the double-hyphen
are interpreted as belonging to omnitrace and all arguments following the double-hyphen are interpreted as the
application and it's arguments. In binary rewrite mode, all application arguments after the first argument
are ignored, i.e. `./omnitrace -o ls.inst -- ls -l` interprets `ls` as the target to instrument (ignores the `-l` argument)
are ignored, i.e. `./omnitrace-instrument -o ls.inst -- ls -l` interprets `ls` as the target to instrument (ignores the `-l` argument)
and generates a `ls.inst` executable that you can subsequently run `ls.inst -l` with.
## Runtime Instrumentation
```shell
omnitrace <omnitrace-options> -- <exe> [<exe-options>...]
omnitrace-instrument <omnitrace-options> -- <exe> [<exe-options>...]
```
## Attaching to Running Process
```shell
omnitrace <omnitrace-options> -p <PID> -- <exe-name>
omnitrace-instrument <omnitrace-options> -p <PID> -- <exe-name>
```
## Binary Rewrite
```shell
omnitrace <omnitrace-options> -o <name-of-new-exe-or-library> -- <exe-or-library>
omnitrace-instrument <omnitrace-options> -o <name-of-new-exe-or-library> -- <exe-or-library>
```
### Binary Rewriting a Library
@@ -249,8 +392,8 @@ $ ldd /usr/local/bin/foo
Generate binary rewrites of `foo` and `libfoo.so.2`:
```shell
omnitrace -o ./foo.inst -- foo
omnitrace -o ./libfoo.so.2 -- /usr/local/lib/libfoo.so.2
omnitrace-instrument -o ./foo.inst -- foo
omnitrace-instrument -o ./libfoo.so.2 -- /usr/local/lib/libfoo.so.2
```
At this point, the instrumented `foo.inst` executable will still dynamically load the original `libfoo.so.2` in `/usr/local/lib`:
@@ -279,11 +422,15 @@ $ ldd ./foo.inst
## Selective Instrumentation
The default behavior of omnitrace does not instrument every symbol in the binary. These default rules are:
The default behavior of omnitrace-instrument does not instrument every symbol in the binary. These default rules are:
- Skip instrumenting dynamic call-sites (i.e. function pointers)
- Option `--dynamic-callsites` will force instrumentation for all dynamic call-sites
- The cost of a function can be loosely approximated by the size of the function in the binary so by default, omnitrace only instruments functions which span an address range of 256 bytes.
- The cost of a function can be loosely approximated by the number of instruction so by default, omnitrace-instrument only instruments functions with at least 1024 instructions
- Option `--min-instructions` will modify this heuristic for all functions which do not contain loops
- Option `--min-instructions-loop` will modify this heuristic for functions which contain loops
- This separate loop option is provided because functions with loops can be compact in the binary while also being costly
- The cost of a function can be also be loosely approximated by the size of the function in the binary so this heuristic can also be used in lieu of or in addition to the minimum number of instructions
- Option `--min-address-range` will modify this heuristic for all functions which do not contain loops
- Option `--min-address-range-loop` will modify this heuristic for functions which contain loops
- This separate loop option is provided because functions with loops can be compact in the binary while also being costly
@@ -296,17 +443,17 @@ The default behavior of omnitrace does not instrument every symbol in the binary
### Viewing the Available, Instrumented, Excluded, and Overlapping Functions
Whenever omnitrace is executed with a verbosity of zero or higher, it emits files which detail which functions (and which module they were defined in)
Whenever omnitrace-instrument is executed with a verbosity of zero or higher, it emits files which detail which functions (and which module they were defined in)
were available for instrumentation, which functions were instrumented, which functions were excluded, and which functions contained overlapping function bodies.
The default output path of these files will be in a `omnitrace-<NAME>-output` folder where `<NAME>` is the basename of the targeted binary or
(in the case of binary rewrite, the basename of the resulting executable), e.g.
`omnitrace -- ls` will output it's files to `omnitrace-ls-output` whereas `omnitrace -o ls.inst -- ls` will output to `omnitrace-ls.inst-output`.
`omnitrace-instrument -- ls` will output it's files to `omnitrace-ls-output` whereas `omnitrace-instrument -o ls.inst -- ls` will output to `omnitrace-ls.inst-output`.
If you would like to generate these files without executing or generating an executable, use the `--simulate` option:
```shell
omnitrace --simulate -- foo
omnitrace --simulate -o foo.inst -- foo
omnitrace-instrument --simulate -- foo
omnitrace-instrument --simulate -o foo.inst -- foo
```
### Excluding and Including Modules and Functions
@@ -326,7 +473,7 @@ These options are always applied regardless of whether the module or function sa
#### Example Available Module and Function Info Output
> ***`omnitrace -o lulesh.inst --label file line args --simulate -- lulesh`***
> ***`omnitrace-instrument -o lulesh.inst --label file line args --simulate -- lulesh`***
```console
AddressRange Module Function FunctionSignature
@@ -544,7 +691,7 @@ These options are always applied regardless of whether the module or function sa
#### Example Instrumented Module and Function Info Output
> ***`omnitrace -o lulesh.inst --label file line args --simulate -- lulesh`***
> ***`omnitrace-instrument -o lulesh.inst --label file line args --simulate -- lulesh`***
After the heuristics are applied in [Example Available Module and Function Info Output](#example-available-module-and-function-info-output),
the selected module/functions are:
@@ -610,7 +757,9 @@ the selected module/functions are:
## Sampling
By default, omnitrace uses `--mode trace` for instrumentation. The `--mode sampling` option
> ***NOTE: This capability has been deprecated in favor of [omnitrace-sample](sampling.md)***
By default, omnitrace-instrument uses `--mode trace` for instrumentation. The `--mode sampling` option
will only instrument `main` in an executable and will activate both CPU call-stack sampling and
background system-level thread sampling by default.
Tracing capabilities which do not rely on instrumentation, such as the HIP API and kernel tracing
@@ -629,7 +778,7 @@ binary may be used later in a different login sessions when the environment may
For example, if the following sequence of commands are run:
```shell
omnitrace -o ./foo.inst -- ./foo
omnitrace-instrument -o ./foo.inst -- ./foo
export OMNITRACE_USE_SAMPLING=ON
export OMNITRACE_SAMPLING_FREQ=5
./foo.inst
@@ -638,7 +787,7 @@ export OMNITRACE_SAMPLING_FREQ=5
These configuration settings will not be preserved in another session, whereas:
```shell
omnitrace -o ./foo.samp --env OMNITRACE_USE_SAMPLING=ON OMNITRACE_SAMPLING_FREQ=5 -- ./foo
omnitrace-instrument -o ./foo.samp --env OMNITRACE_USE_SAMPLING=ON OMNITRACE_SAMPLING_FREQ=5 -- ./foo
```
will preserve those environment variables:
@@ -21,7 +21,7 @@ export OMNITRACE_USE_PERFETTO=ON
```
```shell
$ omnitrace -- ./foo
$ omnitrace-instrument -- ./foo
...
[omnitrace] Outputting 'omnitrace-example-output/perfetto-trace.proto'...
@@ -33,7 +33,7 @@ If we enable the `OMNITRACE_USE_PID` option, then when our non-MPI executable is
```shell
$ export OMNITRACE_USE_PID=ON
$ omnitrace -- ./foo
$ omnitrace-instrument -- ./foo
...
[omnitrace] Outputting 'omnitrace-example-output/perfetto-trace-63453.proto'...
@@ -45,7 +45,7 @@ If we enable `OMNITRACE_TIME_OUTPUT`, then a job started on January 31, 2022 at
```shell
$ export OMNITRACE_TIME_OUTPUT=ON
$ omnitrace -- ./foo
$ omnitrace-instrument -- ./foo
...
[omnitrace] Outputting 'omnitrace-example-output/2022-01-31_12.30_PM/perfetto-trace-63453.proto'...
@@ -14,14 +14,14 @@ Call-stack sampling can be activated with either a binary instrumented via the `
- Binary rewrite with only instrumentation necessary to start/stop sampling
```console
omnitrace -M sampling -o foo.inst -- foo
omnitrace-instrument -M sampling -o foo.inst -- foo
./foo.inst
```
- Runtime instrumentation with only instrumentation necessary to start/stop sampling
```console
omnitrace -M sampling -- foo
omnitrace-instrument -M sampling -- foo
```
- No instrumentation required
@@ -30,17 +30,17 @@ omnitrace -M sampling -- foo
omnitrace-sample -- foo
```
All `omnitrace -M sampling` (referred to as "instrumented-sampling" henceforth) does is wrap the `main` of the executable with initialization
All `omnitrace-instrument -M sampling` (referred to as "instrumented-sampling" henceforth) does is wrap the `main` of the executable with initialization
before `main` starts and finalization after `main` ends.
This can be easily accomplished without instrumentation via a `LD_PRELOAD` of a library with containing a dynamic symbol wrapper around `__libc_start_main`.
Thus, whenever binary instrumentation is unnecessary, using `omnitrace-sample` is recommended over `omnitrace -M sampling` for several reasons:
Thus, whenever binary instrumentation is unnecessary, using `omnitrace-sample` is recommended over `omnitrace-instrument -M sampling` for several reasons:
1. `omnitrace-sample` provides command-line options for controlling features of omnitrace instead of *requiring* configuration files or environment variables
2. Despite the fact that instrumented-sampling only requires inserting snippets around one function (`main`), Dyninst
does not have a feature for specifying that parsing and processing all the other symbols in the binary is unnecessary,
thus, in the best case scenario, instrumented-sampling has a slightly slower launch time when the target binary is relatively small
but, in the worst case scenarios, requires a significant amount of time and memory to launch
3. `omnitrace-sample` is fully compatible with MPI, e.g. `mpirun -n 2 omnitrace-sample -- foo`, whereas `mpirun -n 2 omnitrace -M sampling -- foo`
3. `omnitrace-sample` is fully compatible with MPI, e.g. `mpirun -n 2 omnitrace-sample -- foo`, whereas `mpirun -n 2 omnitrace-instrument -M sampling -- foo`
is incompatible with some MPI distributions (particularly OpenMPI) because of MPI restrictions against forking within an MPI rank
- If you recall, when MPI and binary instrumentation is involved, two steps are involed: (1) do a binary rewrite of the executable
and (2) use the instrumented executable in leiu of the original executable. `omnitrace-sample` is thus much easier to use with MPI.
@@ -39,7 +39,7 @@ If all the following commands execute successfully with output, then you are rea
which omnitrace
which omnitrace-avail
which omnitrace-sample
omnitrace --help
omnitrace-instrument --help
omnitrace-avail --all
omnitrace-sample --help
@@ -167,7 +167,7 @@ custom_push_region(const char* name)
### User API Output
```console
$ omnitrace -l --min-instructions=8 -E custom_push_region -o -- ./user-api
$ omnitrace-instrument -l --min-instructions=8 -E custom_push_region -o -- ./user-api
...
$ export OMNITRACE_USE_TIMEMORY=ON
$ export OMNITRACE_USE_PID=OFF
@@ -26,7 +26,7 @@ endif()
add_test(
NAME omnitrace-invalid-config
COMMAND $<TARGET_FILE:omnitrace-exe> -- ${_CONFIG_TEST_EXE}
COMMAND $<TARGET_FILE:omnitrace-instrument> -- ${_CONFIG_TEST_EXE}
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(
@@ -37,7 +37,7 @@ set_tests_properties(
add_test(
NAME omnitrace-missing-config
COMMAND $<TARGET_FILE:omnitrace-exe> -- ${_CONFIG_TEST_EXE}
COMMAND $<TARGET_FILE:omnitrace-instrument> -- ${_CONFIG_TEST_EXE}
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(
@@ -905,9 +905,9 @@ if(TARGET parallel-overhead AND _VALID_PTRACE_SCOPE)
add_test(
NAME parallel-overhead-attach
COMMAND
${CMAKE_CURRENT_LIST_DIR}/run-omnitrace-pid.sh $<TARGET_FILE:omnitrace-exe>
-ME "\.c$" -E fib -e -v 1 --label return args file -l --
$<TARGET_FILE:parallel-overhead> 30 8 1000
${CMAKE_CURRENT_LIST_DIR}/run-omnitrace-pid.sh
$<TARGET_FILE:omnitrace-instrument> -ME "\.c$" -E fib -e -v 1 --label return
args file -l -- $<TARGET_FILE:parallel-overhead> 30 8 1000
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set(_parallel_overhead_attach_environ
@@ -426,7 +426,7 @@ function(OMNITRACE_ADD_TEST)
add_test(
NAME ${TEST_NAME}-binary-rewrite
COMMAND
$<TARGET_FILE:omnitrace-exe> -o
$<TARGET_FILE:omnitrace-instrument> -o
$<TARGET_FILE_DIR:${TEST_TARGET}>/${TEST_NAME}.inst
${TEST_REWRITE_ARGS} -- $<TARGET_FILE:${TEST_TARGET}>
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
@@ -443,7 +443,7 @@ function(OMNITRACE_ADD_TEST)
add_test(
NAME ${TEST_NAME}-binary-rewrite-sampling
COMMAND
$<TARGET_FILE:omnitrace-exe> -o
$<TARGET_FILE:omnitrace-instrument> -o
$<TARGET_FILE_DIR:${TEST_TARGET}>/${TEST_NAME}.samp -M sampling
${TEST_REWRITE_ARGS} -- $<TARGET_FILE:${TEST_TARGET}>
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
@@ -459,7 +459,7 @@ function(OMNITRACE_ADD_TEST)
if(NOT TEST_SKIP_RUNTIME AND NOT OMNITRACE_USE_SANITIZER)
add_test(
NAME ${TEST_NAME}-runtime-instrument
COMMAND $<TARGET_FILE:omnitrace-exe> ${TEST_RUNTIME_ARGS} --
COMMAND $<TARGET_FILE:omnitrace-instrument> ${TEST_RUNTIME_ARGS} --
$<TARGET_FILE:${TEST_TARGET}> ${TEST_RUN_ARGS}
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
endif()
@@ -468,8 +468,9 @@ function(OMNITRACE_ADD_TEST)
AND NOT OMNITRACE_USE_SANITIZER)
add_test(
NAME ${TEST_NAME}-runtime-instrument-sampling
COMMAND $<TARGET_FILE:omnitrace-exe> -M sampling ${TEST_RUNTIME_ARGS} --
$<TARGET_FILE:${TEST_TARGET}> ${TEST_RUN_ARGS}
COMMAND
$<TARGET_FILE:omnitrace-instrument> -M sampling ${TEST_RUNTIME_ARGS}
-- $<TARGET_FILE:${TEST_TARGET}> ${TEST_RUN_ARGS}
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
endif()