diff --git a/tests/bpf2c_tests/elf_bpf.cpp b/tests/bpf2c_tests/elf_bpf.cpp index bf0646814e..247d971f34 100644 --- a/tests/bpf2c_tests/elf_bpf.cpp +++ b/tests/bpf2c_tests/elf_bpf.cpp @@ -319,3 +319,56 @@ TEST_CASE("bad malformed ELF", "[bpf2c_cli]") REQUIRE(err == expected_error); } } + +TEST_CASE("Verbose output", "[bpf2c_cli]") +{ + std::string non_verbose_error; + std::string verbose_error; + auto test = [&](bool verbose) -> std::string { + std::vector argv; + argv.push_back("bpf2c.exe"); + argv.push_back("--bpf"); + argv.push_back("droppacket_unsafe.o"); + if (verbose) { + argv.push_back("--verbose"); + } + auto [out, err, result_value] = run_test_main(argv); + REQUIRE(result_value != 0); + REQUIRE(!err.empty()); + REQUIRE(err.find("Verification failed for DropPacket with error Verification failed") != std::string::npos); + return err; + }; + + non_verbose_error = test(false); + verbose_error = test(true); + + REQUIRE(non_verbose_error != verbose_error); + REQUIRE(non_verbose_error.length() < verbose_error.length()); + + // Count Pre-Invariant and Post-Invariant lines in the verbose output. + int pre_invariant = 0; + int post_invariant = 0; + std::istringstream verbose_stream(verbose_error); + std::string line; + while (std::getline(verbose_stream, line)) { + if (line.find("Pre-invariant") != std::string::npos) { + pre_invariant++; + } + if (line.find("Post-invariant") != std::string::npos) { + post_invariant++; + } + } + + REQUIRE(pre_invariant == 25); + REQUIRE(post_invariant == 25); + + // Check to make sure that the verbose flag doesn't cause verification to fail. + std::vector argv; + argv.push_back("bpf2c.exe"); + argv.push_back("--bpf"); + argv.push_back("droppacket.o"); + argv.push_back("--verbose"); + auto [out, err, result_value] = run_test_main(argv); + REQUIRE(result_value == 0); + REQUIRE(err.empty()); +} \ No newline at end of file diff --git a/tests/sample/sample.vcxproj b/tests/sample/sample.vcxproj index 19445a4134..aefe9e93b1 100644 --- a/tests/sample/sample.vcxproj +++ b/tests/sample/sample.vcxproj @@ -303,7 +303,7 @@ $(ClangExec) $(ClangFlags) -I../xdp -I../socket -I./ext/inc -I../../netebpfext -I. -I../../undocked/tests/sample/ext/inc -c undocked\%(Filename).c -o $(OutputPath)%(Filename).o pushd $(OutDir) - powershell -NonInteractive -ExecutionPolicy Unrestricted .\Convert-BpfToNative.ps1 -FileName %(Filename) -IncludeDir $(SolutionDir)\include -Platform $(Platform) -Packages $(SolutionDir)\packages -Configuration $(KernelConfiguration) -KernelMode $true + powershell -NonInteractive -ExecutionPolicy Unrestricted .\Convert-BpfToNative.ps1 -FileName %(Filename) -IncludeDir $(SolutionDir)\include -Platform $(Platform) -Packages $(SolutionDir)\packages -Configuration $(KernelConfiguration) -KernelMode $true -Verbose powershell -NonInteractive -ExecutionPolicy Unrestricted .\Convert-BpfToNative.ps1 -FileName %(Filename) -IncludeDir $(SolutionDir)\include -Platform $(Platform) -Packages $(SolutionDir)\packages -Configuration $(Configuration) -KernelMode $false popd diff --git a/tools/bpf2c/Convert-BpfToNative.ps1.template b/tools/bpf2c/Convert-BpfToNative.ps1.template index fb0835022e..9767913349 100644 --- a/tools/bpf2c/Convert-BpfToNative.ps1.template +++ b/tools/bpf2c/Convert-BpfToNative.ps1.template @@ -122,6 +122,10 @@ if ($PSBoundParameters.ContainsKey("Type")) { $AdditionalOptions += " --type $Type" } +if ($VerbosePreference -eq "Continue") { + $AdditionalOptions += " --verbose" +} + msbuild /p:BinDir="$BinDir\" /p:OutDir="$OutDir\" /p:IncludeDir="$IncludeDir" /p:Configuration="$Configuration" /p:Platform="$Platform" /p:FileName="$FileName" /p:AdditionalOptions="$AdditionalOptions" /p:ResourceFile="$ResourceFile" /p:Packages="$Packages" $ProjectFile if ($LASTEXITCODE -ne 0) { diff --git a/tools/bpf2c/bpf2c.cpp b/tools/bpf2c/bpf2c.cpp index 8d3bce4763..84731278d8 100644 --- a/tools/bpf2c/bpf2c.cpp +++ b/tools/bpf2c/bpf2c.cpp @@ -143,6 +143,7 @@ main(int argc, char** argv) std::string output_file_name; std::string type_string = ""; std::string hash_algorithm = EBPF_HASH_ALGORITHM; + bool verbose = false; std::vector parameters(argv + 1, argv + argc); auto iter = parameters.begin(); auto iter_end = parameters.end(); @@ -227,6 +228,12 @@ main(int argc, char** argv) } return false; }}}, + {"--verbose", + {"Show verbose failure information", + [&]() { + verbose = true; + return true; + }}}, }; for (; iter != iter_end; ++iter) { @@ -305,7 +312,7 @@ main(int argc, char** argv) program->section_name, program->program_name, (global_program_type_set) ? &program_type : &program->program_type, - EBPF_VERIFICATION_VERBOSITY_NORMAL, + verbose ? EBPF_VERIFICATION_VERBOSITY_INFORMATIONAL : EBPF_VERIFICATION_VERBOSITY_NORMAL, &report, &error_message, &stats) != 0) {