Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve tools #60

Merged
merged 8 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ jobs:
with:
name: snail-tools-${{ matrix.arch }}-${{ matrix.platform }}
path: |
${{ github.workspace }}/install/tools/bin/app_*
${{ github.workspace }}/install/tools/bin/snail-tool-*
${{ github.workspace }}/install/tools/bin/info.txt

deploy-head:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/clang-format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Run clang-format
uses: DoozyX/[email protected]
with:
source: './snail ./tests ./apps'
source: './snail ./tests ./tools'
exclude: './snail/common/third_party'
extensions: 'cpp,hpp'
clangFormatVersion: 16
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ add_subdirectory(snail)

if(SNAIL_BUILD_TOOLS)
# Just for testing/development
add_subdirectory(apps)
add_subdirectory(tools)
endif()

# =======
Expand Down
20 changes: 0 additions & 20 deletions apps/CMakeLists.txt

This file was deleted.

54 changes: 41 additions & 13 deletions snail/etl/etl_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <iostream>
#include <queue>
#include <stdexcept>
#include <utility>

#include <snail/common/cast.hpp>

Expand Down Expand Up @@ -67,7 +68,9 @@

buffer_info read_buffer(std::ifstream& file_stream,
std::streampos buffer_start_pos,
std::array<std::byte, max_buffer_size>& buffer_data)
std::array<std::byte, max_buffer_size>& buffer_data,
const etl_file::header_data& file_header_,
event_observer& callbacks)
{
file_stream.seekg(buffer_start_pos);
file_stream.read(reinterpret_cast<char*>(buffer_data.data()), common::narrow_cast<std::streamsize>(buffer_data.size()));
Expand All @@ -86,6 +89,8 @@

const auto header = parser::wmi_buffer_header_view(header_buffer);

callbacks.handle_buffer(file_header_, header);

if(header.wnode().buffer_size() > total_buffer.size())
{
throw std::runtime_error(std::format(
Expand All @@ -101,6 +106,13 @@
read_bytes));
}

if((header.buffer_flag() & std::to_underlying(parser::etw_buffer_flag::compressed)) != 0)
{
throw std::runtime_error(std::format(
"Unsupported ETL file: Buffer {} is marked as compressed, but compressed buffers are not yet supported.",
header.wnode().sequence_number()));

Check warning on line 113 in snail/etl/etl_file.cpp

View check run for this annotation

Codecov / codecov/patch

snail/etl/etl_file.cpp#L111-L113

Added lines #L111 - L113 were not covered by tests
}

const auto payload_size = header.wnode().saved_offset() - parser::wmi_buffer_header_view::static_size;
const auto payload_buffer = total_buffer.subspan(parser::wmi_buffer_header_view::static_size, payload_size);

Expand Down Expand Up @@ -303,25 +315,37 @@

const auto buffer_header = parser::wmi_buffer_header_view(file_buffer);

assert(buffer_header.buffer_type() == parser::etw_buffer_type::header);
if(buffer_header.buffer_type() != parser::etw_buffer_type::header)
{
throw std::runtime_error("Invalid ETL file: invalid buffer header type");

Check warning on line 320 in snail/etl/etl_file.cpp

View check run for this annotation

Codecov / codecov/patch

snail/etl/etl_file.cpp#L320

Added line #L320 was not covered by tests
}

if(read_bytes < buffer_header.wnode().saved_offset())
{
throw std::runtime_error("Invalid ETL file: insufficient size for buffer");
}

[[maybe_unused]] const auto marker = parser::generic_trace_marker_view(file_buffer.subspan(parser::wmi_buffer_header_view::static_size));
assert(marker.is_trace_header() && marker.is_trace_header_event_trace() && !marker.is_trace_message());
assert(marker.header_type() == parser::trace_header_type::system32 ||
marker.header_type() == parser::trace_header_type::system64);
const auto marker = parser::generic_trace_marker_view(file_buffer.subspan(parser::wmi_buffer_header_view::static_size));
if(!marker.is_trace_header() || !marker.is_trace_header_event_trace() || marker.is_trace_message())
{
throw std::runtime_error("Invalid ETL file: invalid trace marker");

Check warning on line 331 in snail/etl/etl_file.cpp

View check run for this annotation

Codecov / codecov/patch

snail/etl/etl_file.cpp#L331

Added line #L331 was not covered by tests
}
if(marker.header_type() != parser::trace_header_type::system32 &&
marker.header_type() != parser::trace_header_type::system64)
{
throw std::runtime_error("Invalid ETL file: invalid trace header type");

Check warning on line 336 in snail/etl/etl_file.cpp

View check run for this annotation

Codecov / codecov/patch

snail/etl/etl_file.cpp#L336

Added line #L336 was not covered by tests
}

const auto system_trace_header = parser::system_trace_header_view(file_buffer.subspan(
parser::wmi_buffer_header_view::static_size));

// the first record needs to be a event-trace-header
assert(system_trace_header.packet().group() == parser::event_trace_group::header);
assert(system_trace_header.packet().type() == 0);
assert(system_trace_header.version() == 2);
if(system_trace_header.packet().group() != parser::event_trace_group::header ||
system_trace_header.packet().type() != 0 ||
system_trace_header.version() != 2)
{
throw std::runtime_error("Invalid ETL file: invalid initial event trace header record.");

Check warning on line 347 in snail/etl/etl_file.cpp

View check run for this annotation

Codecov / codecov/patch

snail/etl/etl_file.cpp#L347

Added line #L347 was not covered by tests
}

const auto header_event = parser::event_trace_v2_header_event_view(file_buffer.subspan(
parser::wmi_buffer_header_view::static_size +
Expand Down Expand Up @@ -419,7 +443,10 @@

processor_data.current_buffer_info = read_buffer(file_stream_,
remaining_buffers.back().start_pos,
processor_data.current_buffer_data);
processor_data.current_buffer_data,
header_,
callbacks);

remaining_buffers.pop_back();

event_queue.push(next_event_priority_info{
Expand Down Expand Up @@ -454,8 +481,6 @@
const auto buffer_exhausted = buffer_info.current_payload_offset >= buffer_info.payload_buffer.size();
if(buffer_exhausted)
{
callbacks.handle_buffer(header_, parser::wmi_buffer_header_view(buffer_info.header_buffer));

auto& remaining_buffers = processor_data.remaining_buffers;

// If there are no remaining buffers for this processor, stop extracting events for it.
Expand All @@ -465,7 +490,10 @@
// Keep in mind, that `remaining_buffers` is sorted.
buffer_info = read_buffer(file_stream_,
remaining_buffers.back().start_pos,
processor_data.current_buffer_data);
processor_data.current_buffer_data,
header_,
callbacks);

remaining_buffers.pop_back();
}

Expand Down
2 changes: 1 addition & 1 deletion third-party/gtest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG b796f7d44681514f58a683a3a71ff17c94edb0c1 # v1.13.0
GIT_TAG f8d7d77c06936315286eb55f8de22cd23c188571 # v1.14.0
SYSTEM
)

Expand Down
23 changes: 23 additions & 0 deletions tools/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@


add_executable(snail_tool_etl etl_file.cpp)
target_link_libraries(snail_tool_etl PRIVATE compile_options etl utf8cpp)
set_target_properties(snail_tool_etl PROPERTIES OUTPUT_NAME "snail-tool-etl")

add_executable(snail_tool_perf_data perf_data_file.cpp)
target_link_libraries(snail_tool_perf_data PRIVATE compile_options perf_data)
set_target_properties(snail_tool_perf_data PROPERTIES OUTPUT_NAME "snail-tool-perfdata")

add_executable(snail_tool_analysis analysis.cpp)
target_link_libraries(snail_tool_analysis PRIVATE compile_options analysis)
set_target_properties(snail_tool_analysis PROPERTIES OUTPUT_NAME "snail-tool-analysis")

install(
TARGETS
snail_tool_etl
snail_tool_perf_data
snail_tool_analysis
COMPONENT
tools
RUNTIME DESTINATION bin
)
File renamed without changes.
18 changes: 17 additions & 1 deletion apps/etl_file.cpp → tools/etl_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,14 @@ int main(int argc, char* argv[])
return EXIT_FAILURE;
}

std::cout << std::format(" start_time: {}\n", file.header().start_time);
std::cout << std::format(" end_time: {}\n", file.header().end_time);
std::cout << std::format(" start_time_qpc_ticks: {}\n", file.header().start_time_qpc_ticks);
std::cout << std::format(" qpc_frequency: {}\n", file.header().qpc_frequency);
std::cout << std::format(" pointer_size: {}\n", file.header().pointer_size);
std::cout << std::format(" number_of_processors: {}\n", file.header().number_of_processors);
std::cout << std::format(" number_of_buffers: {}\n", file.header().number_of_buffers);

counting_event_observer observer;

std::size_t sample_count = 0;
Expand Down Expand Up @@ -1054,7 +1062,15 @@ int main(int argc, char* argv[])
}

std::cout << "\n";
file.process(observer);
try
{
file.process(observer);
}
catch(const std::exception& e)
{
std::cerr << std::format("Failed to process ETL file: {}\n", e.what());
return EXIT_FAILURE;
}

std::cout << "\n";
std::cout << "Number of samples:\n";
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading