This repository was archived by the owner on Aug 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
add code coverage host functions #10933
Open
praphael
wants to merge
35
commits into
develop-boxed
Choose a base branch
from
pdr-EPE-1812_eos-vm-coverage-host-functions
base: develop-boxed
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 33 commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
7021484
add code coverage host functions
praphael 9cbe513
code coverage now protocol feature instead of genesis
praphael 1c67d03
add coverage_get_XXX() and coverage_reset() host functions
praphael f7d3423
correct intrinsic name
praphael 2de3068
Revert "correct intrinsic name"
praphael 4b5a68d
Revert "add coverage_get_XXX() and coverage_reset() host functions"
praphael 57ca0e9
Revert "code coverage now protocol feature instead of genesis"
praphael 73acc24
Revert "add code coverage host functions"
praphael 74afa6f
add coverage intrinsics to eosio-tester
praphael 9a05ec3
fix validation-reflect test failures, add param to covergae dump
praphael 4a31d3b
rodeos coverage callbacks
praphael 56e9f2f
add coverage intrinisic to eos-vm-oc
praphael ad65b38
whitelist tester intrinsics
praphael 7e6b809
back to host function (verified working, generate coverage report)
praphael 24ba301
missed changes from prior checkin
praphael c078fac
move rodoes coverage state to global
praphael 033d0df
update programs/eosio-tester/main.cpp
praphael 25c6b14
Refactor code coverage host functions to remove need for protocol fea…
heifner 931775a
rm unused file
heifner e7ce00d
Additional cleanup
heifner 1190d85
whitespace cleanup
heifner 7d143da
Fix oc build
heifner 52fe79e
Add missing returns
heifner 475bc5a
Add missing returns
heifner 443b964
new function coverage_dump_funcnt replaces coverage_dump
praphael 9b75c43
separate coverage maps for chain/rodeos
praphael 13a4795
reduce new coverage host functions to two
praphael c5d2347
Merge branch 'develop-boxed' of https://github.com/EOSIO/eos into pdr…
praphael 7cd129d
remove improper semicolon in libraries/rodeos/include/eosio/coverage.hpp
praphael 8308aa1
fix eosio-tester/main.cpp return paths
praphael 2e3d942
address PR feedback
praphael ad98dff
address PR feedback
praphael 284f478
address PR feedback
praphael 60b8601
use static_cast to fix compile errors
praphael 44720fd
Merge branch 'develop-boxed' of https://github.com/EOSIO/eos into pdr…
praphael File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| #pragma once | ||
|
|
||
| #include <b1/rodeos/callbacks/vm_types.hpp> | ||
| #include <eosio/coverage.hpp> | ||
|
|
||
| namespace b1::rodeos { | ||
|
|
||
| using eosio::coverage::coverage_maps; | ||
| using eosio::coverage::coverage_mode; | ||
|
|
||
| constexpr auto rodeos_n = eosio::name{"rodeos"}.value; | ||
|
|
||
| struct coverage_state { | ||
| }; | ||
|
|
||
| template <typename Derived> | ||
| struct coverage_callbacks { | ||
| Derived& derived() { return static_cast<Derived&>(*this); } | ||
|
|
||
| uint32_t coverage_getinc(uint64_t code, uint32_t file_num, uint32_t func_or_line_num, uint32_t mode, bool inc) { | ||
| if(inc) { | ||
| if (mode == coverage_mode::func) { | ||
| eosio::coverage::coverage_inc_cnt(code, file_num, func_or_line_num, coverage_maps<rodeos_n>::instance().funcnt_map); | ||
| } else if (mode == coverage_mode::line) { | ||
| eosio::coverage::coverage_inc_cnt(code, file_num, func_or_line_num, coverage_maps<rodeos_n>::instance().linecnt_map); | ||
| } | ||
| } | ||
| else { | ||
| if (mode == coverage_mode::func) { | ||
| return eosio::coverage::coverage_get_cnt(code, file_num, func_or_line_num, coverage_maps<rodeos_n>::instance().funcnt_map); | ||
| } | ||
| else if (mode == coverage_mode::line) { | ||
| return eosio::coverage::coverage_get_cnt(code, file_num, func_or_line_num, coverage_maps<rodeos_n>::instance().linecnt_map); | ||
| } | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| uint64_t coverage_dump(uint64_t code, uint32_t file_num, eosio::vm::span<const char> file_name, uint32_t max, bool append, uint32_t mode, bool reset) { | ||
| if (reset) { | ||
| coverage_maps<rodeos_n>::instance().funcnt_map.clear(); | ||
| coverage_maps<rodeos_n>::instance().linecnt_map.clear(); | ||
| } | ||
| else if (mode == coverage_mode::func) { | ||
| return eosio::coverage::coverage_dump(code, file_num, file_name.data(), file_name.size(), max, append, coverage_maps<rodeos_n>::instance().funcnt_map); | ||
| } | ||
| else if (mode == coverage_mode::line) { | ||
| return eosio::coverage::coverage_dump(code, file_num, file_name.data(), file_name.size(), max, append, coverage_maps<rodeos_n>::instance().linecnt_map); | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| template <typename Rft> | ||
| static void register_callbacks() { | ||
| // todo: preconditions | ||
| RODEOS_REGISTER_CALLBACK(Rft, Derived, coverage_getinc); | ||
| RODEOS_REGISTER_CALLBACK(Rft, Derived, coverage_dump); | ||
| } | ||
| }; // coverage_callbacks | ||
|
|
||
| } // namespace b1::rodeos |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| #pragma once | ||
|
|
||
| #include <eosio/chain/name.hpp> | ||
| #include <unordered_map> | ||
| #include <string> | ||
| #include <fstream> | ||
|
|
||
| using cov_map_t = std::unordered_map<uint64_t, std::unordered_map<uint32_t, std::unordered_map<uint32_t, uint32_t> > >; | ||
|
|
||
| // rodeos lib is not the ideal location for this as it is also used by eosio-tester but rodeos lib keeps it out of nodeos | ||
| namespace eosio { | ||
| namespace coverage { | ||
|
|
||
| template<uint64_t Unique> | ||
| class coverage_maps { | ||
| public: | ||
| static coverage_maps& instance() { | ||
| static coverage_maps instance; | ||
| return instance; | ||
| } | ||
| coverage_maps(const coverage_maps&) = delete; | ||
| void operator=(const coverage_maps&) = delete; | ||
|
|
||
| cov_map_t funcnt_map; | ||
| cov_map_t linecnt_map; | ||
| private: | ||
| coverage_maps() = default; | ||
| }; | ||
|
|
||
| enum class coverage_mode : uint32_t { | ||
| func=0, | ||
| line=1 | ||
| }; | ||
|
|
||
| inline void coverage_inc_cnt( uint64_t code, uint32_t file_num, uint32_t func_or_line_num, cov_map_t& cov_map) { | ||
| auto& code_map = cov_map[code]; | ||
| auto& cnt_map = code_map[file_num]; | ||
| cnt_map[func_or_line_num]++; | ||
| } | ||
|
|
||
| inline uint32_t coverage_get_cnt( uint64_t code, uint32_t file_num, uint32_t func_or_line_num, cov_map_t& cov_map) { | ||
| auto& code_map = cov_map[code]; | ||
| auto& cnt_map = code_map[file_num]; | ||
| return cnt_map[func_or_line_num]; | ||
| } | ||
|
|
||
| // dump coverage output (function or line) to binary file | ||
| // if code == 0, begin at first code in the map | ||
| // max is only checked for every code, so it is possible to exceed the number | ||
| // if max == 0, then only dump coverage for specific code and specific file_num | ||
| // in theis case code must be > 0 | ||
| // returns the next code, or 0 if at end | ||
| inline uint64_t coverage_dump(uint64_t code, uint32_t file_num, const char* file_name, uint32_t file_name_size, uint32_t max, bool append, cov_map_t& cov_map) { | ||
| std::ofstream out_bin_file; | ||
| auto flags = std::ofstream::out | std::ofstream::binary; | ||
| if (append) | ||
| flags = flags | std::ofstream::app; | ||
| else | ||
| flags = flags | std::ofstream::trunc; | ||
|
|
||
| ilog("coverage_dump_funcnt: file_name= ${f} max= ${max} ${app}", ("f", file_name)("nax", max)("app", append)); | ||
| out_bin_file.open(file_name, flags ); | ||
| uint32_t i = 0; | ||
| auto code_itr = cov_map.begin(); | ||
| if (max == 0 && code == 0) { | ||
| elog("coverage_dump_funcnt: when max == 0, code must be > 0"); | ||
| return 0; | ||
| } | ||
| if (code > 0) { | ||
| code_itr = cov_map.find(code); | ||
| } | ||
| while (code_itr != cov_map.end() && (max == 0 || i < max)) { | ||
| auto codenum = code_itr->first; | ||
| auto& filenum_map = code_itr->second; | ||
| auto filenum_itr = filenum_map.begin(); | ||
| if (max == 0) { | ||
| filenum_itr = filenum_map.find(file_num); | ||
| } | ||
| while (filenum_itr != filenum_map.end()) { | ||
| auto filenum = filenum_itr->first; | ||
| auto& funcnum_map = filenum_itr->second; | ||
| for (const auto& funcnum_itr : funcnum_map) { | ||
| auto func_or_line_num = funcnum_itr.first; | ||
| auto calls = funcnum_itr.second; | ||
| out_bin_file.write(reinterpret_cast<const char*>(&codenum), sizeof(code)); | ||
| out_bin_file.write(reinterpret_cast<const char*>(&filenum), sizeof(filenum)); | ||
| out_bin_file.write(reinterpret_cast<const char*>(&func_or_line_num), sizeof(func_or_line_num)); | ||
| out_bin_file.write(reinterpret_cast<const char*>(&calls), sizeof(calls)); | ||
| ++i; | ||
| } | ||
| ++filenum_itr; | ||
| if (max == 0) | ||
| break; | ||
| } | ||
| ++code_itr; | ||
| if (max == 0) | ||
| break; | ||
| } | ||
|
|
||
| out_bin_file.flush(); | ||
| out_bin_file.close(); | ||
|
|
||
| uint64_t r = 0; | ||
| if(code_itr != cov_map.end()) | ||
| r = code_itr->first; | ||
| return r; | ||
| } | ||
|
|
||
| } // namespace coverage | ||
| } // namespace eosio | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.