Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

add code coverage host functions #10933

Open
wants to merge 35 commits into
base: develop-boxed
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
7021484
add code coverage host functions
praphael Dec 6, 2021
9cbe513
code coverage now protocol feature instead of genesis
praphael Dec 7, 2021
1c67d03
add coverage_get_XXX() and coverage_reset() host functions
praphael Dec 7, 2021
f7d3423
correct intrinsic name
praphael Dec 7, 2021
2de3068
Revert "correct intrinsic name"
praphael Dec 8, 2021
4b5a68d
Revert "add coverage_get_XXX() and coverage_reset() host functions"
praphael Dec 8, 2021
57ca0e9
Revert "code coverage now protocol feature instead of genesis"
praphael Dec 8, 2021
73acc24
Revert "add code coverage host functions"
praphael Dec 8, 2021
74afa6f
add coverage intrinsics to eosio-tester
praphael Dec 8, 2021
9a05ec3
fix validation-reflect test failures, add param to covergae dump
praphael Dec 8, 2021
4a31d3b
rodeos coverage callbacks
praphael Dec 9, 2021
56e9f2f
add coverage intrinisic to eos-vm-oc
praphael Dec 9, 2021
ad65b38
whitelist tester intrinsics
praphael Dec 10, 2021
7e6b809
back to host function (verified working, generate coverage report)
praphael Dec 11, 2021
24ba301
missed changes from prior checkin
praphael Dec 14, 2021
c078fac
move rodoes coverage state to global
praphael Jan 4, 2022
033d0df
update programs/eosio-tester/main.cpp
praphael Jan 11, 2022
25c6b14
Refactor code coverage host functions to remove need for protocol fea…
heifner Jan 17, 2022
931775a
rm unused file
heifner Jan 17, 2022
e7ce00d
Additional cleanup
heifner Jan 17, 2022
1190d85
whitespace cleanup
heifner Jan 17, 2022
7d143da
Fix oc build
heifner Jan 18, 2022
52fe79e
Add missing returns
heifner Jan 21, 2022
475bc5a
Add missing returns
heifner Jan 25, 2022
443b964
new function coverage_dump_funcnt replaces coverage_dump
praphael Feb 2, 2022
9b75c43
separate coverage maps for chain/rodeos
praphael Feb 3, 2022
13a4795
reduce new coverage host functions to two
praphael Feb 3, 2022
c5d2347
Merge branch 'develop-boxed' of https://github.com/EOSIO/eos into pdr…
praphael Feb 4, 2022
7cd129d
remove improper semicolon in libraries/rodeos/include/eosio/coverage.hpp
praphael Feb 4, 2022
8308aa1
fix eosio-tester/main.cpp return paths
praphael Feb 4, 2022
2e3d942
address PR feedback
praphael Feb 7, 2022
ad98dff
address PR feedback
praphael Feb 7, 2022
284f478
address PR feedback
praphael Feb 7, 2022
60b8601
use static_cast to fix compile errors
praphael Feb 7, 2022
44720fd
Merge branch 'develop-boxed' of https://github.com/EOSIO/eos into pdr…
praphael Feb 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libraries/chain/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ set(CHAIN_WEBASSEMBLY_SOURCES
webassembly/compiler_builtins.cpp
webassembly/context_free.cpp
webassembly/console.cpp
webassembly/coverage.cpp
webassembly/crypto.cpp
webassembly/database.cpp
webassembly/kv_database.cpp
Expand Down
14 changes: 14 additions & 0 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ struct controller_impl {
set_activation_handler<builtin_protocol_feature_t::kv_database>();
set_activation_handler<builtin_protocol_feature_t::configurable_wasm_limits>();
set_activation_handler<builtin_protocol_feature_t::blockchain_parameters>();
set_activation_handler<builtin_protocol_feature_t::wasm_code_coverage>();

self.irreversible_block.connect([this](const block_state_ptr& bsp) {
wasmif.current_lib(bsp->block_num);
Expand Down Expand Up @@ -3456,6 +3457,19 @@ void controller_impl::on_activation<builtin_protocol_feature_t::blockchain_param
} );
}

template<>
void controller_impl::on_activation<builtin_protocol_feature_t::wasm_code_coverage>() {
db.modify( db.get<protocol_state_object>(), [&]( auto& ps ) {
add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "coverage_inc_fun_cnt" );
add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "coverage_inc_line_cnt" );
add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "coverage_get_fun_cnt" );
add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "coverage_get_line_cnt" );
add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "coverage_dump" );
add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "coverage_reset" );
} );
}


/// End of protocol feature activation handlers

} } /// eosio::chain
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ enum class builtin_protocol_feature_t : uint32_t {
action_return_value,
kv_database,
configurable_wasm_limits,
blockchain_parameters
blockchain_parameters,
wasm_code_coverage
};

struct protocol_feature_subjective_restrictions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,13 @@ constexpr auto intrinsic_table = boost::hana::make_tuple(
"env.push_data"_s,
"env.print_time_us"_s,
"env.get_input_data"_s,
"env.set_output_data"_s
"env.set_output_data"_s,
"env.coverage_inc_fun_cnt"_s,
"env.coverage_inc_line_cnt"_s,
"env.coverage_get_fun_cnt"_s,
"env.coverage_get_line_cnt"_s,
"env.coverage_dump"_s,
"env.coverage_reset"_s
);

}}}
8 changes: 8 additions & 0 deletions libraries/chain/include/eosio/chain/webassembly/interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1897,6 +1897,14 @@ namespace eosio { namespace chain { namespace webassembly {
int32_t __lttf2(uint64_t, uint64_t, uint64_t, uint64_t) const;
int32_t __unordtf2(uint64_t, uint64_t, uint64_t, uint64_t) const;

// code coverage support functions
void coverage_inc_fun_cnt(account_name code, uint32_t file_num, uint32_t func_num);
void coverage_inc_line_cnt(account_name code, uint32_t file_num, uint32_t line_num);
uint32_t coverage_get_fun_cnt(account_name code, uint32_t file_num, uint32_t func_num);
uint32_t coverage_get_line_cnt(account_name code, uint32_t file_num, uint32_t line_num);
void coverage_dump();
void coverage_reset();

private:
apply_context& context;
};
Expand Down
94 changes: 94 additions & 0 deletions libraries/chain/webassembly/coverage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include <eosio/chain/webassembly/interface.hpp>

#include <unordered_map>
#include <fstream>

namespace eosio { namespace chain { namespace webassembly {
static std::unordered_map<name, std::unordered_map<uint32_t, std::unordered_map<uint32_t, uint32_t> > > funcnt_map;
static std::unordered_map<name, std::unordered_map<uint32_t, std::unordered_map<uint32_t, uint32_t> > > linecnt_map;

void interface::coverage_inc_fun_cnt(account_name code, uint32_t file_num, uint32_t func_num) {
auto &code_map = funcnt_map[code];
auto &funcnt = code_map[file_num];
funcnt[func_num]++;
}

void interface::coverage_inc_line_cnt(account_name code, uint32_t file_num, uint32_t line_num) {
auto &code_map = linecnt_map[code];
auto &linecnt = code_map[file_num];
linecnt[line_num]++;
}

uint32_t interface::coverage_get_fun_cnt(account_name code, uint32_t file_num, uint32_t func_num) {
uint32_t ret_val = 0;
if (funcnt_map.count(code) > 0) {
auto &code_map = funcnt_map[code];
if (code_map.count(file_num) > 0) {
auto &funcnt = code_map[file_num];
if (funcnt.count(func_num) > 0) {
ret_val = funcnt[func_num];
}
}
}
return ret_val;
}

uint32_t interface::coverage_get_line_cnt(account_name code, uint32_t file_num, uint32_t line_num) {
uint32_t ret_val = 0;
if (linecnt_map.count(code) > 0) {
auto &code_map = linecnt_map[code];
if (code_map.count(file_num) > 0) {
auto &linecnt = code_map[file_num];
if (linecnt.count(line_num) > 0) {
ret_val = linecnt[line_num];
}
}
}
return ret_val;
}

void interface::coverage_dump() {
auto fName = std::string("call-counts.json");
std::ofstream out_json_file;
out_json_file.open(fName);

// dont use auto JSON serialization because
// we want to convert maps to arrays
out_json_file << "{\n";
out_json_file << "\t\"functions\": {";
for (auto code_map : funcnt_map) {
auto code_str = code_map.first.to_string();
out_json_file << "\t\t\"" << code_str <<"\": [\n";
for (auto funcnt : code_map.second) {
auto file_num = funcnt.first;
for (auto func : funcnt.second) {
auto func_num = func.first;
auto calls = func.second;
out_json_file << "\t\t\t[" << file_num << ", " << func_num << ", " << calls << "]\n";
}
}
out_json_file << "\t\t]\n";
}
out_json_file << "\t}\n";

out_json_file << "\t\"lines\": {";
for (auto code_map : linecnt_map) {
auto code_str = code_map.first.to_string();
out_json_file << "{ \"" << code_str <<"\"";

for (auto linecnt : code_map.second) {
for (auto line : linecnt.second) {

}
}
out_json_file << "]\n";
}
out_json_file << "\t}\n";
out_json_file.close();
}

void interface::coverage_reset() {
funcnt_map.clear();
linecnt_map.clear();
}
}}}
8 changes: 8 additions & 0 deletions libraries/chain/webassembly/runtimes/eos-vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,14 @@ REGISTER_CF_HOST_FUNCTION(__letf2);
REGISTER_CF_HOST_FUNCTION(__lttf2);
REGISTER_CF_HOST_FUNCTION(__unordtf2);

// code coverage API
REGISTER_HOST_FUNCTION(coverage_inc_fun_cnt)
REGISTER_HOST_FUNCTION(coverage_inc_line_cnt)
REGISTER_HOST_FUNCTION(coverage_get_fun_cnt)
REGISTER_HOST_FUNCTION(coverage_get_line_cnt)
REGISTER_HOST_FUNCTION(coverage_dump)
REGISTER_HOST_FUNCTION(coverage_reset)

} // namespace webassembly
} // namespace chain
} // namespace eosio