Release 0.0.2 (#14)
* Fixed Dyninst TBB symbolic links + bump to v0.0.2 * hosttrace exe and library updates + submodule updates - Updated dyninst submodule with TBB build ORIGIN rpath - Updated timemory submodule - Dyninst build with shared libs - Dockerfile for building packaging - Disable hidden viz in examples - parallel-overhead max parallelism - query_instr in hosttrace - different file-line info format - full module names - minor fix to MPI support - disable instrumention stack frames by default - disable trap instrumentation by default - updated hosttrace output file dumps - removed cstdlib option - dyninst DebugParsing option - improved instrument_module function - fixed some MPI support - tweaked some testing parameters
This commit is contained in:
zatwierdzone przez
GitHub
rodzic
6c93674f92
commit
02f59ec9dc
+196
-57
@@ -31,6 +31,8 @@
|
||||
static bool is_driver = false;
|
||||
static bool allow_overlapping = false;
|
||||
static bool instr_dynamic_callsites = false;
|
||||
static bool instr_traps = false;
|
||||
static bool instr_loop_traps = false;
|
||||
static size_t batch_size = 50;
|
||||
static strset_t extra_libs = {};
|
||||
static size_t min_address_range = (1 << 9); // 512
|
||||
@@ -54,7 +56,7 @@ static string_t instr_pop_hash = "hosttrace_pop_trace_hash";
|
||||
static string_t print_instrumented = {};
|
||||
static string_t print_available = {};
|
||||
static string_t print_overlapping = {};
|
||||
static std::string modfunc_dump_dir = "hosttrace-module-functions";
|
||||
static std::string modfunc_dump_dir = {};
|
||||
|
||||
std::string
|
||||
get_absolute_exe_filepath(std::string exe_name);
|
||||
@@ -114,14 +116,14 @@ main(int argc, char** argv)
|
||||
bpatch->setTypeChecking(true);
|
||||
bpatch->setSaveFPR(true);
|
||||
bpatch->setDelayedParsing(true);
|
||||
bpatch->setInstrStackFrames(true);
|
||||
bpatch->setDebugParsing(false);
|
||||
bpatch->setInstrStackFrames(false);
|
||||
bpatch->setLivenessAnalysis(false);
|
||||
bpatch->setBaseTrampDeletion(false);
|
||||
bpatch->setTrampRecursive(false);
|
||||
bpatch->setMergeTramp(false);
|
||||
|
||||
std::set<std::string> dyninst_defs = { "TypeChecking", "SaveFPR", "DelayedParsing",
|
||||
"InstrStackFrames" };
|
||||
std::set<std::string> dyninst_defs = { "TypeChecking", "SaveFPR", "DelayedParsing" };
|
||||
|
||||
int _argc = argc;
|
||||
int _cmdc = 0;
|
||||
@@ -329,14 +331,35 @@ main(int argc, char** argv)
|
||||
parser
|
||||
.add_argument({ "--min-address-range-loop" },
|
||||
"If the address range of a function containing a loop is less than "
|
||||
"this value, "
|
||||
"exclude it from instrumentation")
|
||||
"this value, exclude it from instrumentation")
|
||||
.count(1)
|
||||
.dtype("size_t")
|
||||
.set_default(min_loop_address_range)
|
||||
.action([](parser_t& p) {
|
||||
min_loop_address_range = p.get<size_t>("min-address-range-loop");
|
||||
});
|
||||
parser
|
||||
.add_argument(
|
||||
{ "--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 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. In this case, Dyninst replaces the "
|
||||
"instruction with a single-byte instruction that generates a trap.")
|
||||
.max_count(1)
|
||||
.dtype("bool")
|
||||
.set_default(instr_traps)
|
||||
.action([](parser_t& p) { instr_traps = p.get<bool>("traps"); });
|
||||
parser
|
||||
.add_argument({ "--loop-traps" },
|
||||
"Instrument points within a loop which require using a trap (only "
|
||||
"relevant when --instrument-loops is enabled).")
|
||||
.max_count(1)
|
||||
.dtype("bool")
|
||||
.set_default(instr_loop_traps)
|
||||
.action([](parser_t& p) { instr_loop_traps = p.get<bool>("loop-traps"); });
|
||||
parser.add_argument()
|
||||
.names({ "--allow-overlapping" })
|
||||
.description(
|
||||
@@ -352,7 +375,6 @@ main(int argc, char** argv)
|
||||
"function lists, e.g. {print-dir}/available.txt")
|
||||
.count(1)
|
||||
.dtype("string")
|
||||
.set_default(modfunc_dump_dir)
|
||||
.action([](parser_t& p) { modfunc_dump_dir = p.get<std::string>("print-dir"); });
|
||||
parser
|
||||
.add_argument(
|
||||
@@ -397,8 +419,9 @@ main(int argc, char** argv)
|
||||
.add_argument({ "--dyninst-options" },
|
||||
"Advanced dyninst options: BPatch::set<OPTION>(bool), e.g. "
|
||||
"bpatch->setTrampRecursive(true)")
|
||||
.choices({ "TypeChecking", "SaveFPR", "DelayedParsing", "InstrStackFrames",
|
||||
"TrampRecursive", "MergeTramp", "BaseTrampDeletion" });
|
||||
.choices({ "TypeChecking", "SaveFPR", "DebugParsing", "DelayedParsing",
|
||||
"InstrStackFrames", "TrampRecursive", "MergeTramp",
|
||||
"BaseTrampDeletion" });
|
||||
|
||||
string_t extra_help = "-- <CMD> <ARGS>";
|
||||
auto err = parser.parse(_argc, _argv);
|
||||
@@ -483,8 +506,6 @@ main(int argc, char** argv)
|
||||
|
||||
if(parser.exists("S")) stl_func_instr = true;
|
||||
|
||||
if(parser.exists("cstdlib")) cstd_func_instr = true;
|
||||
|
||||
if(parser.exists("mpi")) use_mpi = true;
|
||||
|
||||
if(parser.exists("p")) _pid = parser.get<int>("p");
|
||||
@@ -554,6 +575,15 @@ main(int argc, char** argv)
|
||||
fini_stub_names = parser.get<strvec_t>("fini-functions");
|
||||
auto env_vars = parser.get<strvec_t>("env");
|
||||
|
||||
if(modfunc_dump_dir.empty())
|
||||
{
|
||||
auto _exe_base = (binary_rewrite) ? outfile : std::string{ cmdv0 };
|
||||
auto _pos = _exe_base.find_last_of('/');
|
||||
if(_pos != std::string::npos && _pos + 1 < _exe_base.length())
|
||||
_exe_base = _exe_base.substr(_pos + 1);
|
||||
modfunc_dump_dir = TIMEMORY_JOIN("-", "hosttrace", _exe_base, "output");
|
||||
}
|
||||
|
||||
if(verbose_level >= 0) tim::makedir(modfunc_dump_dir);
|
||||
|
||||
//----------------------------------------------------------------------------------//
|
||||
@@ -622,8 +652,9 @@ main(int argc, char** argv)
|
||||
bpatch->setTypeChecking(get_dyninst_option("TypeChecking"));
|
||||
bpatch->setSaveFPR(get_dyninst_option("SaveFPR"));
|
||||
bpatch->setDelayedParsing(get_dyninst_option("DelayedParsing"));
|
||||
bpatch->setInstrStackFrames(get_dyninst_option("InstrStackFrames"));
|
||||
|
||||
bpatch->setDebugParsing(get_dyninst_option("DebugParsing"));
|
||||
bpatch->setInstrStackFrames(get_dyninst_option("InstrStackFrames"));
|
||||
bpatch->setTrampRecursive(get_dyninst_option("TrampRecursive"));
|
||||
bpatch->setMergeTramp(get_dyninst_option("MergeTramp"));
|
||||
bpatch->setBaseTrampDeletion(get_dyninst_option("BaseTrampDeletion"));
|
||||
@@ -764,21 +795,28 @@ main(int argc, char** argv)
|
||||
module_function::update_width(itr);
|
||||
|
||||
auto mwid = module_function::get_width().at(0);
|
||||
auto ncol = 240 / std::min<size_t>(mwid, 240);
|
||||
mwid = std::min<size_t>(mwid, 90);
|
||||
auto ncol = 180 / std::min<size_t>(mwid, 180);
|
||||
std::cout << "### MODULES ###\n| ";
|
||||
for(size_t i = 0; i < module_names.size(); ++i)
|
||||
{
|
||||
auto itr = module_names.begin();
|
||||
std::advance(itr, i);
|
||||
std::cout << std::setw(mwid) << *itr << " | ";
|
||||
std::string _v = *itr;
|
||||
if(_v.length() >= mwid)
|
||||
{
|
||||
auto _resume = _v.length() - mwid + 15;
|
||||
_v = _v.substr(0, 12) + "..." + _v.substr(_resume);
|
||||
}
|
||||
std::cout << std::setw(mwid) << _v << " | ";
|
||||
if(i % ncol == ncol - 1) std::cout << "\n| ";
|
||||
}
|
||||
std::cout << '\n' << std::endl;
|
||||
}
|
||||
|
||||
dump_info(TIMEMORY_JOIN('/', modfunc_dump_dir, "available.txt"),
|
||||
dump_info(TIMEMORY_JOIN('/', modfunc_dump_dir, "available-instr.txt"),
|
||||
available_module_functions, 1);
|
||||
dump_info(TIMEMORY_JOIN('/', modfunc_dump_dir, "overlapping.txt"),
|
||||
dump_info(TIMEMORY_JOIN('/', modfunc_dump_dir, "overlapping-instr.txt"),
|
||||
overlapping_module_functions, 1);
|
||||
|
||||
//----------------------------------------------------------------------------------//
|
||||
@@ -1065,8 +1103,8 @@ main(int argc, char** argv)
|
||||
module_t* _module = _func->getModule();
|
||||
if(_module)
|
||||
{
|
||||
char moduleName[MUTNAMELEN];
|
||||
_module->getName(moduleName, MUTNAMELEN);
|
||||
char moduleName[FUNCNAMELEN];
|
||||
_module->getFullName(moduleName, FUNCNAMELEN);
|
||||
if(strcmp(moduleName, "DEFAULT_MODULE") != 0) _has_debug_info = true;
|
||||
}
|
||||
}
|
||||
@@ -1283,16 +1321,26 @@ main(int argc, char** argv)
|
||||
(unsigned long) procedures.size());
|
||||
for(auto* itr : procedures)
|
||||
{
|
||||
if(itr == main_func) continue;
|
||||
|
||||
char modname[MUTNAMELEN];
|
||||
if(!itr) continue;
|
||||
char modname[FUNCNAMELEN];
|
||||
char fname[FUNCNAMELEN];
|
||||
|
||||
itr->getName(fname, FUNCNAMELEN);
|
||||
module_t* mod = itr->getModule();
|
||||
if(mod)
|
||||
mod->getName(modname, MUTNAMELEN);
|
||||
mod->getFullName(modname, FUNCNAMELEN);
|
||||
else
|
||||
itr->getModuleName(modname, MUTNAMELEN);
|
||||
itr->getModuleName(modname, FUNCNAMELEN);
|
||||
|
||||
if(itr == main_func)
|
||||
{
|
||||
hash_ids.emplace_back(std::hash<string_t>()(main_sign.get()),
|
||||
main_sign.get());
|
||||
auto main_mf = module_function(modname, fname, main_sign, itr);
|
||||
available_module_functions.insert(main_mf);
|
||||
instrumented_module_functions.insert(main_mf);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!itr->isInstrumentable())
|
||||
{
|
||||
@@ -1303,11 +1351,8 @@ main(int argc, char** argv)
|
||||
if(std::string{ modname }.find("libdyninst") != std::string::npos) continue;
|
||||
|
||||
if(module_constraint(modname)) continue;
|
||||
|
||||
if(!instrument_module(modname)) continue;
|
||||
|
||||
itr->getName(fname, FUNCNAMELEN);
|
||||
|
||||
auto name = get_func_file_line_info(mod, itr);
|
||||
|
||||
if(name.get().empty())
|
||||
@@ -1317,7 +1362,6 @@ main(int argc, char** argv)
|
||||
}
|
||||
|
||||
if(routine_constraint(name.m_name.c_str())) continue;
|
||||
|
||||
if(!instrument_entity(name.m_name)) continue;
|
||||
|
||||
if(is_static_exe && has_debug_info && string_t{ fname } == "_fini" &&
|
||||
@@ -1392,6 +1436,29 @@ main(int argc, char** argv)
|
||||
(unsigned long) min_address_range);
|
||||
}
|
||||
|
||||
bool _entr_success =
|
||||
query_instr(itr, BPatch_entry, nullptr, nullptr, instr_traps);
|
||||
bool _exit_success =
|
||||
query_instr(itr, BPatch_exit, nullptr, nullptr, instr_traps);
|
||||
if(!_entr_success && !_exit_success)
|
||||
{
|
||||
verbprintf(2,
|
||||
"Skipping function [insert-instr]: %s / %s. Either no entry "
|
||||
"instrumentation points were found or instrumentation "
|
||||
"required traps and instrumenting via traps were disabled.\n",
|
||||
name.m_name.c_str(), name.get().c_str());
|
||||
continue;
|
||||
}
|
||||
else if(_entr_success && !_exit_success)
|
||||
{
|
||||
verbprintf(2,
|
||||
"Skipping function [insert-instr]: %s / %s. Function can be "
|
||||
"only partially instrumented: entry = %s, exit = %s\n",
|
||||
name.m_name.c_str(), name.get().c_str(),
|
||||
_entr_success ? "y" : "n", _exit_success ? "y" : "n");
|
||||
continue;
|
||||
}
|
||||
|
||||
hash_ids.emplace_back(std::hash<string_t>()(name.get()), name.get());
|
||||
available_module_functions.insert(module_function(mod, itr));
|
||||
instrumented_module_functions.insert(module_function(mod, itr));
|
||||
@@ -1408,8 +1475,10 @@ main(int argc, char** argv)
|
||||
auto _entr = _trace_entr.get((entr_hash) ? entr_hash : entr_trace);
|
||||
auto _exit = _trace_exit.get((exit_hash) ? exit_hash : exit_trace);
|
||||
|
||||
insert_instr(addr_space, itr, _entr, BPatch_entry, nullptr, nullptr);
|
||||
insert_instr(addr_space, itr, _exit, BPatch_exit, nullptr, nullptr);
|
||||
insert_instr(addr_space, itr, _entr, BPatch_entry, nullptr, nullptr,
|
||||
instr_traps);
|
||||
insert_instr(addr_space, itr, _exit, BPatch_exit, nullptr, nullptr,
|
||||
instr_traps);
|
||||
};
|
||||
|
||||
instr_procedure_functions.emplace_back(_f);
|
||||
@@ -1421,6 +1490,31 @@ main(int argc, char** argv)
|
||||
|
||||
for(auto* litr : basic_loop)
|
||||
{
|
||||
bool _lentr_success =
|
||||
query_instr(itr, BPatch_entry, cfg, litr, instr_loop_traps);
|
||||
bool _lexit_success =
|
||||
query_instr(itr, BPatch_exit, cfg, litr, instr_loop_traps);
|
||||
if(!_lentr_success && !_lexit_success)
|
||||
{
|
||||
verbprintf(
|
||||
2,
|
||||
"Skipping function [insert-instr-loop]: %s / %s. Either no "
|
||||
"entry instrumentation points were found or instrumentation "
|
||||
"required traps and instrumenting via traps were disabled.\n",
|
||||
name.m_name.c_str(), name.get().c_str());
|
||||
continue;
|
||||
}
|
||||
else if(_lentr_success && !_lexit_success)
|
||||
{
|
||||
verbprintf(
|
||||
2,
|
||||
"Skipping function [insert-instr-loop]: %s / %s. Function "
|
||||
"can be only partially instrumented: entry = %s, exit = %s\n",
|
||||
name.m_name.c_str(), name.get().c_str(),
|
||||
_lentr_success ? "y" : "n", _lexit_success ? "y" : "n");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto lname = get_loop_file_line_info(mod, itr, cfg, litr);
|
||||
auto _lname = lname.get();
|
||||
auto _lhash = std::hash<string_t>()(_lname);
|
||||
@@ -1437,8 +1531,10 @@ main(int argc, char** argv)
|
||||
auto _lexit =
|
||||
_ltrace_exit.get((exit_hash) ? exit_hash : exit_trace);
|
||||
|
||||
insert_instr(addr_space, itr, _lentr, BPatch_entry, cfg, litr);
|
||||
insert_instr(addr_space, itr, _lexit, BPatch_exit, cfg, litr);
|
||||
insert_instr(addr_space, itr, _lentr, BPatch_entry, cfg, litr,
|
||||
instr_loop_traps);
|
||||
insert_instr(addr_space, itr, _lexit, BPatch_exit, cfg, litr,
|
||||
instr_loop_traps);
|
||||
};
|
||||
instr_procedure_functions.emplace_back(_lf);
|
||||
}
|
||||
@@ -1585,11 +1681,11 @@ main(int argc, char** argv)
|
||||
bool _dump_and_exit = ((print_available.length() + print_instrumented.length() +
|
||||
print_overlapping.length()) > 0);
|
||||
|
||||
dump_info(TIMEMORY_JOIN('/', modfunc_dump_dir, "available.txt"),
|
||||
dump_info(TIMEMORY_JOIN('/', modfunc_dump_dir, "available-instr.txt"),
|
||||
available_module_functions, 0);
|
||||
dump_info(TIMEMORY_JOIN('/', modfunc_dump_dir, "instrumented.txt"),
|
||||
dump_info(TIMEMORY_JOIN('/', modfunc_dump_dir, "instrumented-instr.txt"),
|
||||
instrumented_module_functions, 0);
|
||||
dump_info(TIMEMORY_JOIN('/', modfunc_dump_dir, "overlapping.txt"),
|
||||
dump_info(TIMEMORY_JOIN('/', modfunc_dump_dir, "overlapping-instr.txt"),
|
||||
overlapping_module_functions, 0);
|
||||
|
||||
auto _dump_info = [](string_t _mode, const fmodset_t& _modset) {
|
||||
@@ -1824,12 +1920,15 @@ instrument_module(const string_t& file_name)
|
||||
static std::regex sys_regex("^(s|k|e|w)_[A-Za-z_0-9\\-]+\\.(c|C)$", regex_opts);
|
||||
static std::regex userlib_regex(
|
||||
"^(lib|)(hosttrace|caliper|gotcha|papi|cupti|TAU|likwid|"
|
||||
"profiler|tcmalloc|dyninst|pfm|nvtx|upcxx|pthread|nvperf|hsa)",
|
||||
"profiler|tcmalloc|dyninst|pfm|nvtx|upcxx|pthread|nvperf|hsa|\\.\\./sysdeps/|/"
|
||||
"build/)",
|
||||
regex_opts);
|
||||
static std::regex corelib_regex("^lib(rt-|dl-|util-|python)", regex_opts);
|
||||
static std::regex corelib_regex("^lib(c|z|rt|dl|util|zstd|elf|dw|pthread|dyninstAPI_"
|
||||
"RT|gcc_s|tbbmalloc|tbbmalloc_proxy)(-|\\.)",
|
||||
regex_opts);
|
||||
// these are all due to TAU
|
||||
static std::regex prefix_regex(
|
||||
"^(_|\\.|RT|Tau|Profiler|Rts|Papi|Py|Comp_xl\\.cpp|Comp_gnu\\.cpp|"
|
||||
"^(_|\\.[a-zA-Z0-9]|RT|Tau|Profiler|Rts|Papi|Py|Comp_xl\\.cpp|Comp_gnu\\.cpp|"
|
||||
"UserEvent\\.cpp|FunctionInfo\\.cpp|PthreadLayer\\.cpp|"
|
||||
"Comp_intel[0-9]\\.cpp|Tracer\\.cpp)",
|
||||
regex_opts);
|
||||
@@ -1845,13 +1944,6 @@ instrument_module(const string_t& file_name)
|
||||
"set[a-z_]+|^get[a-z_]+|^shm[a-z]+|^wc[a-z_]+|brk|^write[a-z]+)\\.c$",
|
||||
regex_opts);*/
|
||||
|
||||
/*if(!cstd_func_instr && c_stdlib_module_constraint(file_name))
|
||||
{
|
||||
verbprintf(3, "Excluding instrumentation [c std library] : '%s'...\n",
|
||||
file_name.c_str());
|
||||
return false;
|
||||
}*/
|
||||
|
||||
if(std::regex_search(file_name, ext_regex))
|
||||
{
|
||||
return (_report("Excluding", "file extension", 3), false);
|
||||
@@ -1952,12 +2044,6 @@ instrument_entity(const string_t& function_name)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*if(!cstd_func_instr && c_stdlib_function_constraint(function_name))
|
||||
{
|
||||
verbprintf(3, "Excluding function [libc] : '%s'...\n", function_name.c_str());
|
||||
return false;
|
||||
}*/
|
||||
|
||||
// don't instrument the functions when key is found anywhere in function name
|
||||
if(std::regex_search(function_name, exclude))
|
||||
{
|
||||
@@ -1999,23 +2085,62 @@ instrument_entity(const string_t& function_name)
|
||||
|
||||
bool use = is_include(true) && !is_exclude();
|
||||
if(use)
|
||||
verbprintf(2, "Including function [user-regex] : '%s'...\n",
|
||||
verbprintf(2, "Including function [no constraint] : '%s'...\n",
|
||||
function_name.c_str());
|
||||
|
||||
return use;
|
||||
}
|
||||
|
||||
//======================================================================================//
|
||||
// query_instr -- check whether there are one or more instrumentation points
|
||||
//
|
||||
bool
|
||||
query_instr(procedure_t* funcToInstr, procedure_loc_t traceLoc, flow_graph_t* cfGraph,
|
||||
basic_loop_t* loopToInstrument, bool allow_traps)
|
||||
{
|
||||
module_t* module = funcToInstr->getModule();
|
||||
if(!module) return false;
|
||||
|
||||
bpvector_t<point_t*>* _points = nullptr;
|
||||
|
||||
if(cfGraph && loopToInstrument)
|
||||
{
|
||||
if(traceLoc == BPatch_entry)
|
||||
_points = cfGraph->findLoopInstPoints(BPatch_locLoopEntry, loopToInstrument);
|
||||
else if(traceLoc == BPatch_exit)
|
||||
_points = cfGraph->findLoopInstPoints(BPatch_locLoopExit, loopToInstrument);
|
||||
}
|
||||
else
|
||||
{
|
||||
_points = funcToInstr->findPoint(traceLoc);
|
||||
}
|
||||
|
||||
if(_points == nullptr) return false;
|
||||
if(_points->empty()) return false;
|
||||
|
||||
size_t _n = _points->size();
|
||||
for(auto& itr : *_points)
|
||||
{
|
||||
if(!itr)
|
||||
--_n;
|
||||
else if(itr && !allow_traps && itr->usesTrap_NP())
|
||||
--_n;
|
||||
}
|
||||
|
||||
return (_n > 0);
|
||||
}
|
||||
|
||||
//======================================================================================//
|
||||
// insert_instr -- generic insert instrumentation function
|
||||
//
|
||||
template <typename Tp>
|
||||
void
|
||||
bool
|
||||
insert_instr(address_space_t* mutatee, procedure_t* funcToInstr, Tp traceFunc,
|
||||
procedure_loc_t traceLoc, flow_graph_t* cfGraph,
|
||||
basic_loop_t* loopToInstrument)
|
||||
basic_loop_t* loopToInstrument, bool allow_traps)
|
||||
{
|
||||
module_t* module = funcToInstr->getModule();
|
||||
if(!module || !traceFunc) return;
|
||||
if(!module || !traceFunc) return false;
|
||||
|
||||
bpvector_t<point_t*>* _points = nullptr;
|
||||
auto _trace = traceFunc.get();
|
||||
@@ -2032,8 +2157,8 @@ insert_instr(address_space_t* mutatee, procedure_t* funcToInstr, Tp traceFunc,
|
||||
_points = funcToInstr->findPoint(traceLoc);
|
||||
}
|
||||
|
||||
if(_points == nullptr) return;
|
||||
if(_points->empty()) return;
|
||||
if(_points == nullptr) return false;
|
||||
if(_points->empty()) return false;
|
||||
|
||||
/*if(loop_level_instr)
|
||||
{
|
||||
@@ -2056,9 +2181,19 @@ insert_instr(address_space_t* mutatee, procedure_t* funcToInstr, Tp traceFunc,
|
||||
|
||||
// verbprintf(0, "Instrumenting |> [ %s ]\n", name.m_name.c_str());
|
||||
|
||||
std::set<point_t*> _traps{};
|
||||
if(!allow_traps)
|
||||
{
|
||||
for(auto& itr : *_points)
|
||||
{
|
||||
if(itr && itr->usesTrap_NP()) _traps.insert(itr);
|
||||
}
|
||||
}
|
||||
|
||||
size_t _n = 0;
|
||||
for(auto& itr : *_points)
|
||||
{
|
||||
if(!itr)
|
||||
if(!itr || _traps.count(itr) > 0)
|
||||
continue;
|
||||
else if(traceLoc == BPatch_entry)
|
||||
mutatee->insertSnippet(*_trace, *itr, BPatch_callBefore, BPatch_firstSnippet);
|
||||
@@ -2067,8 +2202,12 @@ insert_instr(address_space_t* mutatee, procedure_t* funcToInstr, Tp traceFunc,
|
||||
// BPatch_firstSnippet);
|
||||
else
|
||||
mutatee->insertSnippet(*_trace, *itr);
|
||||
++_n;
|
||||
}
|
||||
|
||||
return (_n > 0);
|
||||
}
|
||||
|
||||
//======================================================================================//
|
||||
// Constraints for instrumentation. Returns true for those modules that
|
||||
// shouldn't be instrumented.
|
||||
|
||||
Reference in New Issue
Block a user