791375bb24
* Code-coverage support
* Examples update
- code-coverage example
- tweak transpose and parallel-overhead
* Coverage output + testing
- config::get_setting value(...)
- REGULAR_EXPRESSION -> REGEX in cmake func args
- coverage.hpp header
- coverage JSON
- coverage tests
* cmake formatting
* Library instrumentation w/o main + more
- fixed library instrumentation w/o main
- use TIMEMORY_PROJECT_NAME in output messages
- removed '--driver' option from omnitrace exe
- support coverage in trace mode
- OMNITRACE_KOKKOS_KERNEL_LOGGER
- support multiple calls to omnitrace_set_env after init if already called
- support multiple calls to omnitrace_set_mpi after init if same args
- support multiple calls to omnitrace_init if same mode
- unique_ptr_t for thread_data which calls finalize when thread_data is destroyed
- tweaked openmp tests
- improved finalization
* Replace CI --output-on-failure with -V
* Fix to OMNITRACE_DL_INVOKE
* omnitrace-exe and testing updates
- omnitrace::omnitrace-timemory interface library
- support for configs in omnitrace exe
- print-{available,instrumented,...} opts no longer exit w/o --simulate
- all tests apply --print-instrumented functions
- tweaked coverage tests
- print-* options print instructions not address range
* Remove OMNITRACE_DEBUG_FINALIZE=ON from CI
* Python cmake tweaks
* Tweak test ordering
* Upload CI artifacts if fail or success
* CI Python tweaks
- Use OMNITRACE_PYTHON_PREFIX and OMNITRACE_PYTHON_ENVS
* CI ELFULTILS_DOWNLOAD_VERSION
* test tweaks
- labels and more coverage tests
* tweak to omnitrace --config handling
* Update module/function constraint handling + PP
- tweak pre-processor definition handling
- removed free-standing module_constraint
- remove free-standing routine_constraint
- remove module_name.find("omnitrace") module constraint
- fully handle the output path of omnitrace *-instr files
- get_use_code_coverage config option
- print-coverage option
- coverage_module_functions
* use github.job not github.name
* Re-enable HSA_ENABLE_INTERRUPT
- remove coverage address report
300 rader
11 KiB
C++
300 rader
11 KiB
C++
// 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.
|
|
|
|
#pragma once
|
|
|
|
#include <timemory/backends/process.hpp>
|
|
#include <timemory/environment.hpp>
|
|
#include <timemory/mpl/apply.hpp>
|
|
#include <timemory/mpl/concepts.hpp>
|
|
#include <timemory/mpl/policy.hpp>
|
|
#include <timemory/tpls/cereal/archives.hpp>
|
|
#include <timemory/tpls/cereal/cereal.hpp>
|
|
#include <timemory/utility/argparse.hpp>
|
|
#include <timemory/utility/demangle.hpp>
|
|
#include <timemory/utility/popen.hpp>
|
|
#include <timemory/variadic/macros.hpp>
|
|
|
|
#include <BPatch.h>
|
|
#include <BPatch_Vector.h>
|
|
#include <BPatch_addressSpace.h>
|
|
#include <BPatch_basicBlock.h>
|
|
#include <BPatch_basicBlockLoop.h>
|
|
#include <BPatch_callbacks.h>
|
|
#include <BPatch_function.h>
|
|
#include <BPatch_instruction.h>
|
|
#include <BPatch_point.h>
|
|
#include <BPatch_process.h>
|
|
#include <BPatch_snippet.h>
|
|
#include <BPatch_statement.h>
|
|
#include <Instruction.h>
|
|
#include <dyntypes.h>
|
|
|
|
#include <climits>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <exception>
|
|
#include <fstream>
|
|
#include <limits>
|
|
#include <memory>
|
|
#include <numeric>
|
|
#include <ostream>
|
|
#include <regex>
|
|
#include <set>
|
|
#include <sstream>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <unistd.h>
|
|
#include <vector>
|
|
|
|
#define MUTNAMELEN 1024
|
|
#define FUNCNAMELEN 32 * 1024
|
|
#define NO_ERROR -1
|
|
#define TIMEMORY_BIN_DIR "bin"
|
|
|
|
#if !defined(PATH_MAX)
|
|
# define PATH_MAX std::numeric_limits<int>::max();
|
|
#endif
|
|
|
|
struct function_signature;
|
|
struct basic_block_signature;
|
|
struct module_function;
|
|
|
|
template <typename Tp>
|
|
using bpvector_t = BPatch_Vector<Tp>;
|
|
|
|
using string_t = std::string;
|
|
using string_view_t = std::string_view;
|
|
using stringstream_t = std::stringstream;
|
|
using strvec_t = std::vector<string_t>;
|
|
using strset_t = std::set<string_t>;
|
|
using regexvec_t = std::vector<std::regex>;
|
|
using fmodset_t = std::set<module_function>;
|
|
using fixed_modset_t = std::map<fmodset_t*, bool>;
|
|
using exec_callback_t = BPatchExecCallback;
|
|
using exit_callback_t = BPatchExitCallback;
|
|
using fork_callback_t = BPatchForkCallback;
|
|
using patch_t = BPatch;
|
|
using process_t = BPatch_process;
|
|
using thread_t = BPatch_thread;
|
|
using binary_edit_t = BPatch_binaryEdit;
|
|
using image_t = BPatch_image;
|
|
using module_t = BPatch_module;
|
|
using procedure_t = BPatch_function;
|
|
using snippet_t = BPatch_snippet;
|
|
using call_expr_t = BPatch_funcCallExpr;
|
|
using address_space_t = BPatch_addressSpace;
|
|
using flow_graph_t = BPatch_flowGraph;
|
|
using statement_t = BPatch_statement;
|
|
using basic_block_t = BPatch_basicBlock;
|
|
using basic_loop_t = BPatch_basicBlockLoop;
|
|
using procedure_loc_t = BPatch_procedureLocation;
|
|
using point_t = BPatch_point;
|
|
using local_var_t = BPatch_localVar;
|
|
using const_expr_t = BPatch_constExpr;
|
|
using error_level_t = BPatchErrorLevel;
|
|
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>;
|
|
using snippet_vec_t = bpvector_t<snippet_t*>;
|
|
using procedure_vec_t = bpvector_t<procedure_t*>;
|
|
using basic_block_set_t = std::set<basic_block_t*>;
|
|
using basic_loop_vec_t = bpvector_t<basic_loop_t*>;
|
|
using snippet_pointer_vec_t = std::vector<snippet_pointer_t>;
|
|
using instruction_t = Dyninst::InstructionAPI::Instruction;
|
|
|
|
void
|
|
omnitrace_prefork_callback(thread_t* parent, thread_t* child);
|
|
|
|
enum CodeCoverageMode
|
|
{
|
|
CODECOV_NONE = 0,
|
|
CODECOV_FUNCTION,
|
|
CODECOV_BASIC_BLOCK
|
|
};
|
|
|
|
//======================================================================================//
|
|
//
|
|
// Global Variables
|
|
//
|
|
//======================================================================================//
|
|
//
|
|
// label settings
|
|
//
|
|
extern bool use_return_info;
|
|
extern bool use_args_info;
|
|
extern bool use_file_info;
|
|
extern bool use_line_info;
|
|
//
|
|
// heuristic settings
|
|
//
|
|
extern bool allow_overlapping;
|
|
extern bool loop_level_instr;
|
|
extern bool instr_dynamic_callsites;
|
|
extern bool instr_traps;
|
|
extern bool instr_loop_traps;
|
|
extern size_t min_address_range;
|
|
extern size_t min_loop_address_range;
|
|
extern size_t min_instructions;
|
|
extern size_t min_loop_instructions;
|
|
//
|
|
// debug settings
|
|
//
|
|
extern bool werror;
|
|
extern bool debug_print;
|
|
extern bool instr_print;
|
|
extern int verbose_level;
|
|
//
|
|
// string settings
|
|
//
|
|
extern string_t main_fname;
|
|
extern string_t argv0;
|
|
extern string_t cmdv0;
|
|
extern string_t default_components;
|
|
extern string_t prefer_library;
|
|
//
|
|
// global variables
|
|
//
|
|
extern patch_pointer_t bpatch;
|
|
extern call_expr_t* terminate_expr;
|
|
extern snippet_vec_t init_names;
|
|
extern snippet_vec_t fini_names;
|
|
extern fmodset_t available_module_functions;
|
|
extern fmodset_t instrumented_module_functions;
|
|
extern fmodset_t overlapping_module_functions;
|
|
extern fmodset_t excluded_module_functions;
|
|
extern fixed_modset_t fixed_module_functions;
|
|
extern regexvec_t func_include;
|
|
extern regexvec_t func_exclude;
|
|
extern regexvec_t file_include;
|
|
extern regexvec_t file_exclude;
|
|
extern regexvec_t file_restrict;
|
|
extern regexvec_t func_restrict;
|
|
extern CodeCoverageMode coverage_mode;
|
|
//
|
|
//======================================================================================//
|
|
|
|
// control debug printf statements
|
|
#define errprintf(LEVEL, ...) \
|
|
{ \
|
|
if(werror || LEVEL < 0) \
|
|
{ \
|
|
if(debug_print || verbose_level >= LEVEL) \
|
|
fprintf(stderr, "[omnitrace][exe] Error! " __VA_ARGS__); \
|
|
char _buff[FUNCNAMELEN]; \
|
|
sprintf(_buff, "[omnitrace][exe] Error! " __VA_ARGS__); \
|
|
throw std::runtime_error(std::string{ _buff }); \
|
|
} \
|
|
else \
|
|
{ \
|
|
if(debug_print || verbose_level >= LEVEL) \
|
|
fprintf(stderr, "[omnitrace][exe] Warning! " __VA_ARGS__); \
|
|
} \
|
|
fflush(stderr); \
|
|
}
|
|
|
|
// control verbose printf statements
|
|
#define verbprintf(LEVEL, ...) \
|
|
{ \
|
|
if(debug_print || verbose_level >= LEVEL) \
|
|
fprintf(stdout, "[omnitrace][exe] " __VA_ARGS__); \
|
|
fflush(stdout); \
|
|
}
|
|
|
|
#define verbprintf_bare(LEVEL, ...) \
|
|
{ \
|
|
if(debug_print || verbose_level >= LEVEL) fprintf(stdout, __VA_ARGS__); \
|
|
fflush(stdout); \
|
|
}
|
|
|
|
//======================================================================================//
|
|
|
|
template <typename... T>
|
|
void
|
|
consume_parameters(T&&...)
|
|
{}
|
|
|
|
//======================================================================================//
|
|
|
|
extern "C"
|
|
{
|
|
bool are_file_include_exclude_lists_empty();
|
|
bool module_constraint(const char* fname);
|
|
bool routine_constraint(const char* fname);
|
|
}
|
|
|
|
//======================================================================================//
|
|
|
|
strset_t
|
|
get_whole_function_names();
|
|
|
|
function_signature
|
|
get_func_file_line_info(module_t* mutatee_module, procedure_t* f);
|
|
|
|
function_signature
|
|
get_loop_file_line_info(module_t* mutatee_module, procedure_t* f, flow_graph_t* cfGraph,
|
|
basic_loop_t* loopToInstrument);
|
|
|
|
std::map<basic_block_t*, basic_block_signature>
|
|
get_basic_block_file_line_info(module_t* module, procedure_t* func);
|
|
|
|
std::vector<statement_t>
|
|
get_source_code(module_t* module, procedure_t* func);
|
|
|
|
std::tuple<size_t, size_t>
|
|
query_instr(procedure_t* funcToInstr, procedure_loc_t traceLoc,
|
|
flow_graph_t* cfGraph = nullptr, basic_loop_t* loopToInstrument = nullptr);
|
|
|
|
bool
|
|
query_instr(procedure_t* funcToInstr, procedure_loc_t traceLoc, flow_graph_t* cfGraph,
|
|
basic_loop_t* loopToInstrument, bool allow_traps);
|
|
|
|
template <typename Tp>
|
|
bool
|
|
insert_instr(address_space_t* mutatee, const bpvector_t<point_t*>& _points, Tp traceFunc,
|
|
procedure_loc_t traceLoc, bool allow_traps = instr_traps);
|
|
|
|
template <typename Tp>
|
|
bool
|
|
insert_instr(address_space_t* mutatee, procedure_t* funcToInstr, Tp traceFunc,
|
|
procedure_loc_t traceLoc, flow_graph_t* cfGraph = nullptr,
|
|
basic_loop_t* loopToInstrument = nullptr, bool allow_traps = instr_traps);
|
|
|
|
template <typename Tp>
|
|
bool
|
|
insert_instr(address_space_t* mutatee, Tp traceFunc, procedure_loc_t traceLoc,
|
|
basic_block_t* basicBlock, bool allow_traps = instr_traps);
|
|
|
|
void
|
|
errorFunc(error_level_t level, int num, const char** params);
|
|
|
|
procedure_t*
|
|
find_function(image_t* appImage, const string_t& functionName, const strset_t& = {});
|
|
|
|
void
|
|
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);
|