Skip to content

Commit

Permalink
Fix case with unsorted events (#9)
Browse files Browse the repository at this point in the history
* Fix case with unsorted events
  • Loading branch information
mamaria-k committed Jun 9, 2023
1 parent 4cbc9a0 commit aa23f24
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 28 deletions.
101 changes: 73 additions & 28 deletions source/citnames/source/Citnames.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <filesystem>
#include <set>
#include <map>

#ifdef HAVE_FMT_STD_H
#include <fmt/std.h>
Expand All @@ -44,6 +45,11 @@ template <> struct fmt::formatter<cs::Configuration> : ostream_formatter {};

namespace {

struct EventEntries {
std::list<cs::Entry> compile;
std::list<cs::Entry> link;
};

std::list<fs::path> to_abspath(const std::list<fs::path> &paths, const fs::path &root) {
std::list<fs::path> results;
for (const auto &path : paths) {
Expand Down Expand Up @@ -194,15 +200,49 @@ namespace {
});
}

rust::Result<size_t> transform(
cs::semantic::Build &build,
bool transform_event(
const cs::semantic::Build &build,
const rpc::Event &event,
std::map<size_t, EventEntries> &pid_entries,
const bool with_link
) {
const auto get_entries = [](const auto &semantic) -> std::list<cs::Entry> {
const auto candidate = dynamic_cast<const cs::semantic::CompilerCall *>(semantic.get());
return (candidate != nullptr) ? candidate->into_entries() : std::list<cs::Entry>();
};

const size_t pid = event.started().pid();
bool is_written = false;

auto entries_compile = build.recognize(event, cs::semantic::BuildTarget::COMPILER).map<std::list<cs::Entry>>(get_entries).unwrap_or({});
if (!entries_compile.empty()) {
is_written = true;
std::move(entries_compile.begin(), entries_compile.end(), std::back_inserter(pid_entries[pid].compile));
}
if (with_link) {
auto entries_link = build.recognize(event, cs::semantic::BuildTarget::LINKER).map<std::list<cs::Entry>>(get_entries).unwrap_or({});
if (!entries_link.empty()) {
is_written = true;
std::move(entries_link.begin(), entries_link.end(), std::back_inserter(pid_entries[pid].link));
}
}

return is_written;
}

size_t transform(
const cs::semantic::Build &build,
const db::EventsDatabaseReader::Ptr& events,
std::list<cs::Entry> &output_compile,
std::list<cs::Entry> &output_link,
const bool with_link
) {
std::set<size_t> all_ppid;
std::set<size_t> writed_command_pids;
std::set<size_t> writed_event_pids;
std::map<size_t, std::set<size_t>> pid_children;
std::set<size_t> pids_without_parent;
std::set<size_t> pids_with_parent;

std::map<size_t, EventEntries> pid_entries;

for (const rpc::Event &event : *events) {
const size_t pid = event.started().pid();
Expand All @@ -211,38 +251,43 @@ namespace {
continue;
}

if (all_ppid.find(pid) != all_ppid.end()) {
return rust::Err(std::runtime_error("Processes in events database are not sorted!"));
pid_children[ppid].insert(pid);
pids_without_parent.erase(pid);
pids_with_parent.insert(pid);
if (pids_with_parent.find(ppid) == pids_with_parent.end()) {
pids_without_parent.insert(ppid);
}
all_ppid.insert(ppid);

if (writed_command_pids.find(ppid) != writed_command_pids.end()) {
writed_command_pids.insert(pid);
continue;
if (writed_event_pids.find(ppid) != writed_event_pids.end()) {
writed_event_pids.insert(pid);
}
else if (transform_event(build, event, pid_entries, with_link)) {
writed_event_pids.insert(pid);
}
}

const auto get_entries = [](const auto &semantic) -> std::list<cs::Entry> {
const auto candidate = dynamic_cast<const cs::semantic::CompilerCall *>(semantic.get());
return (candidate != nullptr) ? candidate->into_entries() : std::list<cs::Entry>();
};
for (const auto &p : pids_without_parent) {
std::vector<size_t> pids;
std::copy(pid_children[p].rbegin(), pid_children[p].rend(), std::back_inserter(pids));

const auto entries_compile = build.recognize(event, cs::semantic::BuildTarget::COMPILER)
.map<std::list<cs::Entry>>(get_entries).unwrap_or({});
if (!entries_compile.empty()) {
writed_command_pids.insert(pid);
std::copy(entries_compile.begin(), entries_compile.end(), std::back_inserter(output_compile));
}
while (!pids.empty()) {
const auto cur_pid = pids.back();
pids.pop_back();

if (with_link) {
const auto entries_link = build.recognize(event, cs::semantic::BuildTarget::LINKER)
.map<std::list<cs::Entry>>(get_entries).unwrap_or({});
if (!entries_link.empty()) {
writed_command_pids.insert(pid);
std::copy(entries_link.begin(), entries_link.end(), std::back_inserter(output_link));
auto entries_iter = pid_entries.find(cur_pid);
// tree before meaningful event
if (entries_iter == pid_entries.end()) {
std::copy(pid_children[cur_pid].rbegin(), pid_children[cur_pid].rend(), std::back_inserter(pids));
}
// meaningful event, children should not be written
else {
std::move(entries_iter->second.compile.begin(), entries_iter->second.compile.end(), std::back_inserter(output_compile));
std::move(entries_iter->second.link.begin(), entries_iter->second.link.end(), std::back_inserter(output_link));
}
}
}
return rust::Ok(output_compile.size() + output_link.size());

return output_compile.size() + output_link.size();
}

rust::Result<size_t> complete_entries_from_json(
Expand Down Expand Up @@ -286,7 +331,7 @@ namespace cs {
std::list<cs::Entry> entries_link;

return db::EventsDatabaseReader::from(arguments_.input)
.and_then<size_t>([this, &entries_compile, &entries_link](const auto &commands) {
.map<size_t>([this, &entries_compile, &entries_link](const auto &commands) {
cs::semantic::Build build(configuration_.compilation);
return transform(build, commands, entries_compile, entries_link, arguments_.with_link);
})
Expand Down
20 changes: 20 additions & 0 deletions test/cases/citnames/output/unsorted_events.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env sh

# RUN: cd %T; %{shell} %s %t
# RUN: %{citnames} --verbose --input %t.commands.json --output-compile %t.compilations.json
# RUN: assert_compilation %t.compilations.json count -eq 1

cat << EOF > "$1.commands.json"
{"rid":"5208588700335725496","terminated":{"status":"0"},"timestamp":"2023-05-26T11:42:25.573991Z"}
{"rid":"5982815742339840829","started":{"execution":{"executable":"/usr/lib/gcc/x86_64-linux-gnu/11/collect2","arguments":["/usr/lib/gcc/x86_64-linux-gnu/11/collect2"],"working_dir":"example/build","environment":{}},"pid":13896,"ppid":13868},"timestamp":"2023-05-26T11:42:25.580038Z"}
{"rid":"16827070368060185859","started":{"execution":{"executable":"/usr/bin/ld","arguments":["/usr/bin/ld"],"working_dir":"example/build","environment":{}},"pid":13904,"ppid":13896},"timestamp":"2023-05-26T11:42:25.585572Z"}
{"rid":"16827070368060185859","terminated":{"status":"0"},"timestamp":"2023-05-26T11:42:25.638394Z"}
{"rid":"5982815742339840829","terminated":{"status":"0"},"timestamp":"2023-05-26T11:42:25.639796Z"}
{"rid":"11620369640675796770","terminated":{"status":"0"},"timestamp":"2023-05-26T11:42:25.641203Z"}
{"rid":"3208622825367537157","terminated":{"status":"0"},"timestamp":"2023-05-26T11:42:25.642386Z"}
{"rid":"3208622825367537157","started":{"execution":{"executable":"/usr/bin/make","arguments":["make","-f","../Makefile"],"working_dir":"example/build","environment":{}},"pid":13860,"ppid":13847},"timestamp":"2023-05-26T11:42:25.322304Z"}
{"rid":"11620369640675796770","started":{"execution":{"executable":"/usr/bin/g++","arguments":["g++","../main.cpp"],"working_dir":"example/build","environment":{}},"pid":13868,"ppid":13860},"timestamp":"2023-05-26T11:42:25.332432Z"}
{"rid":"1195915605071429231","started":{"execution":{"executable":"/usr/lib/gcc/x86_64-linux-gnu/11/cc1plus","arguments":["/usr/lib/gcc/x86_64-linux-gnu/11/cc1plus"],"working_dir":"example/build","environment":{}},"pid":13876,"ppid":13868},"timestamp":"2023-05-26T11:42:25.345192Z"}
{"rid":"1195915605071429231","terminated":{"status":"0"},"timestamp":"2023-05-26T11:42:25.563234Z"}
{"rid":"5208588700335725496","started":{"execution":{"executable":"/usr/bin/as","arguments":["as"],"working_dir":"example/build","environment":{}},"pid":13888,"ppid":13868},"timestamp":"2023-05-26T11:42:25.568801Z"}
EOF

0 comments on commit aa23f24

Please sign in to comment.