diff --git a/CHANGES b/CHANGES index 04e6ce2f17..ec7897b4db 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +6.0.0-dev.443 | 2023-04-26 12:42:48 -0700 + + * extend ZEEK_PROFILER_FILE profiling to include summaries for functions/hooks/event handlers (Vern Paxson, Corelight) + 6.0.0-dev.441 | 2023-04-26 15:37:59 +0200 * Update AF-Packet submodule (Arne Welzel, Corelight) diff --git a/VERSION b/VERSION index 269c2d5c3a..3f5cfda878 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.0.0-dev.441 +6.0.0-dev.443 diff --git a/src/ScriptCoverageManager.cc b/src/ScriptCoverageManager.cc index ab56f3b793..679bf8e206 100644 --- a/src/ScriptCoverageManager.cc +++ b/src/ScriptCoverageManager.cc @@ -10,8 +10,7 @@ #include "zeek/Desc.h" #include "zeek/Reporter.h" -#include "zeek/Stmt.h" -#include "zeek/util.h" +#include "zeek/Type.h" using namespace std; @@ -20,19 +19,17 @@ namespace zeek::detail ScriptCoverageManager::ScriptCoverageManager() : ignoring(0), delim('\t') { } -ScriptCoverageManager::~ScriptCoverageManager() - { - for ( auto& s : stmts ) - Unref(s); - } - void ScriptCoverageManager::AddStmt(Stmt* s) { if ( ignoring != 0 ) return; - Ref(s); - stmts.push_back(s); + stmts.push_back({NewRef{}, s}); + } + +void ScriptCoverageManager::AddFunction(IDPtr func_id, StmtPtr body) + { + func_instances.push_back({func_id, body}); } bool ScriptCoverageManager::ReadStats() @@ -127,31 +124,47 @@ bool ScriptCoverageManager::WriteStats() return false; } - for ( auto s : stmts ) + for ( auto& s : stmts ) { - ODesc location_info; - s->GetLocationInfo()->Describe(&location_info); ODesc desc_info; s->Describe(&desc_info); - string desc(desc_info.Description()); - canonicalize_desc cd{delim}; - for_each(desc.begin(), desc.end(), cd); - pair location_desc(location_info.Description(), desc); - if ( usage_map.find(location_desc) != usage_map.end() ) - usage_map[location_desc] += s->GetAccessCount(); - else - usage_map[location_desc] = s->GetAccessCount(); + TrackUsage(s, desc_info.Description(), s->GetAccessCount()); } - map, uint64_t>::const_iterator it; - for ( auto& um : usage_map ) + for ( auto& [func, body] : func_instances ) { - fprintf(f, "%" PRIu64 "%c%s%c%s\n", um.second, delim, um.first.first.c_str(), delim, - um.first.second.c_str()); + auto ft = func->GetType(); + auto desc = ft->FlavorString() + " " + func->Name() + " BODY"; + + TrackUsage(body, desc, body->GetAccessCount()); } + for ( auto& [location_info, cnt] : usage_map ) + Report(f, cnt, location_info.first, location_info.second); + fclose(f); return true; } +void ScriptCoverageManager::TrackUsage(const ObjPtr& obj, std::string desc, uint64_t cnt) + { + ODesc location_info; + obj->GetLocationInfo()->Describe(&location_info); + + static canonicalize_desc cd{delim}; + for_each(desc.begin(), desc.end(), cd); + + pair location_desc(location_info.Description(), desc); + + if ( usage_map.find(location_desc) != usage_map.end() ) + usage_map[location_desc] += cnt; + else + usage_map[location_desc] = cnt; + } + +void ScriptCoverageManager::Report(FILE* f, uint64_t cnt, std::string loc, std::string desc) + { + fprintf(f, "%" PRIu64 "%c%s%c%s\n", cnt, delim, loc.c_str(), delim, desc.c_str()); + } + } // namespace zeek::detail diff --git a/src/ScriptCoverageManager.h b/src/ScriptCoverageManager.h index b9c804ad79..72409002cb 100644 --- a/src/ScriptCoverageManager.h +++ b/src/ScriptCoverageManager.h @@ -5,12 +5,14 @@ #include #include +#include "zeek/ID.h" +#include "zeek/StmtBase.h" #include "zeek/util.h" namespace zeek::detail { -class Stmt; +using ObjPtr = IntrusivePtr; /** * A simple class for managing stats of Zeek script coverage across Zeek runs. @@ -19,7 +21,7 @@ class ScriptCoverageManager { public: ScriptCoverageManager(); - virtual ~ScriptCoverageManager(); + virtual ~ScriptCoverageManager() = default; /** * Imports Zeek script Stmt usage information from file pointed to by @@ -46,12 +48,18 @@ public: void DecIgnoreDepth() { ignoring--; } void AddStmt(Stmt* s); + void AddFunction(IDPtr func_id, StmtPtr body); private: /** * The current, global ScriptCoverageManager instance creates this list at parse-time. */ - std::list stmts; + std::list stmts; + + /** + * A similar list for tracking functions and their bodies. + */ + std::list> func_instances; /** * Indicates whether new statements will not be considered as part of @@ -88,6 +96,17 @@ private: c = ' '; } }; + + /** + * Tracks the usage of a given object with a given description + * and a given coverage count. + */ + void TrackUsage(const ObjPtr& obj, std::string desc, uint64_t cnt); + + /** + * Reports a single coverage instance. + */ + void Report(FILE* f, uint64_t cnt, std::string loc, std::string desc); }; extern ScriptCoverageManager script_coverage_mgr; diff --git a/src/Var.cc b/src/Var.cc index 0686363121..d23edc0df8 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -14,6 +14,7 @@ #include "zeek/IntrusivePtr.h" #include "zeek/Reporter.h" #include "zeek/Scope.h" +#include "zeek/ScriptCoverageManager.h" #include "zeek/Stmt.h" #include "zeek/Traverse.h" #include "zeek/Val.h" @@ -859,6 +860,8 @@ void end_func(StmtPtr body, const char* module_name, bool free_of_conditionals) ingredients->FrameSize(), ingredients->Priority(), ingredients->Groups()); + script_coverage_mgr.AddFunction(id, ingredients->Body()); + auto func_ptr = cast_intrusive(id->GetVal())->AsFuncPtr(); auto func = cast_intrusive(func_ptr); func->SetScope(ingredients->Scope()); diff --git a/testing/btest/Baseline/coverage.zeek-profiler-file/step1.out b/testing/btest/Baseline/coverage.zeek-profiler-file/step1.out index dc795e2403..e9b69cafea 100644 --- a/testing/btest/Baseline/coverage.zeek-profiler-file/step1.out +++ b/testing/btest/Baseline/coverage.zeek-profiler-file/step1.out @@ -1,2 +1,3 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. 1 ./profiling-test1.zeek, line 2 print new conn; +1 ./profiling-test1.zeek, lines 1-2 event new_connection BODY diff --git a/testing/btest/Baseline/coverage.zeek-profiler-file/step2.out b/testing/btest/Baseline/coverage.zeek-profiler-file/step2.out index 4247325597..62505a3666 100644 --- a/testing/btest/Baseline/coverage.zeek-profiler-file/step2.out +++ b/testing/btest/Baseline/coverage.zeek-profiler-file/step2.out @@ -1,2 +1,3 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. 2 ./profiling-test1.zeek, line 2 print new conn; +2 ./profiling-test1.zeek, lines 1-2 event new_connection BODY diff --git a/testing/btest/Baseline/coverage.zeek-profiler-file/step3.out b/testing/btest/Baseline/coverage.zeek-profiler-file/step3.out index 5fa4d0b749..7e37b66ce2 100644 --- a/testing/btest/Baseline/coverage.zeek-profiler-file/step3.out +++ b/testing/btest/Baseline/coverage.zeek-profiler-file/step3.out @@ -1,3 +1,5 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. 2 ./profiling-test1.zeek, line 2 print new conn; +2 ./profiling-test1.zeek, lines 1-2 event new_connection BODY 1 ./profiling-test2.zeek, line 2 print new conn; +1 ./profiling-test2.zeek, lines 1-2 event new_connection BODY