diff --git a/centipede/BUILD b/centipede/BUILD index 94134488b..d173db671 100644 --- a/centipede/BUILD +++ b/centipede/BUILD @@ -109,6 +109,7 @@ cc_library( ":util", "@com_google_absl//absl/log", "@com_google_absl//absl/log:check", + "@com_google_absl//absl/status", "@com_google_absl//absl/strings", "@com_google_absl//absl/types:span", ], diff --git a/centipede/symbol_table.cc b/centipede/symbol_table.cc index fefd6e0a7..37b7da666 100644 --- a/centipede/symbol_table.cc +++ b/centipede/symbol_table.cc @@ -20,10 +20,14 @@ #include #include #include +#include #include "absl/log/check.h" #include "absl/log/log.h" +#include "absl/strings/match.h" +#include "absl/strings/numbers.h" #include "absl/strings/str_cat.h" +#include "absl/strings/str_split.h" #include "absl/strings/strip.h" #include "absl/types/span.h" #include "./centipede/command.h" @@ -34,10 +38,6 @@ namespace centipede { -bool SymbolTable::Entry::operator==(const Entry &other) const { - return this->func == other.func && this->file_line_col == other.file_line_col; -} - bool SymbolTable::operator==(const SymbolTable &other) const { return this->entries_ == other.entries_; } @@ -63,8 +63,8 @@ void SymbolTable::ReadFromLLVMSymbolizer(std::istream &in) { void SymbolTable::WriteToLLVMSymbolizer(std::ostream &out) { for (const Entry &entry : entries_) { - out << entry.func << std::endl; - out << entry.file_line_col << std::endl; + out << entry.func << '\n'; + out << entry.file_line_col() << '\n'; out << std::endl; } } @@ -154,4 +154,28 @@ void SymbolTable::SetAllToUnknown(size_t size) { } } +void SymbolTable::AddEntry(std::string_view func, + std::string_view file_line_col) { + if (absl::StrContains(file_line_col, "?")) { + entries_.emplace_back( + Entry{std::string(func), std::string(file_line_col), 0, 0}); + return; + } + const std::vector file_line_col_split = + absl::StrSplit(file_line_col, ':'); + CHECK_EQ(file_line_col_split.size(), 3) + << "Unexpected symbolizer input format when getting source location: " + << file_line_col; + int line = -1; + int col = -1; + CHECK(absl::SimpleAtoi(file_line_col_split[1], &line)) + << "Unable to convert line number string to an int: " + << file_line_col_split[1]; + CHECK(absl::SimpleAtoi(file_line_col_split[2], &col)) + << "Unable to convert column number string to an int: " + << file_line_col_split[2]; + entries_.emplace_back( + Entry{std::string(func), std::string(file_line_col_split[0]), line, col}); +} + } // namespace centipede diff --git a/centipede/symbol_table.h b/centipede/symbol_table.h index 7dcf06ff0..fd9b24890 100644 --- a/centipede/symbol_table.h +++ b/centipede/symbol_table.h @@ -22,6 +22,13 @@ #include #include +#include "absl/log/check.h" +#include "absl/log/log.h" +#include "absl/status/status.h" +#include "absl/strings/match.h" +#include "absl/strings/numbers.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_split.h" #include "absl/types/span.h" #include "./centipede/control_flow.h" #include "./centipede/pc_info.h" @@ -72,8 +79,8 @@ class SymbolTable { const std::string &func(size_t idx) const { return entries_[idx].func; } // Returns source code location for idx-th entry, - const std::string &location(size_t idx) const { - return entries_[idx].file_line_col; + std::string location(size_t idx) const { + return entries_[idx].file_line_col(); } // Returns a full human-readable description for idx-th entry. @@ -81,19 +88,25 @@ class SymbolTable { return func(idx) + " " + location(idx); } + // Add function name and file location to symbol table. + void AddEntry(std::string_view func, std::string_view file_line_col); + + private: // Defines a symbol table entry. struct Entry { std::string func; - std::string file_line_col; - bool operator==(const Entry &other) const; + std::string file; + int line = -1; + int col = -1; + bool operator==(const Entry &other) const = default; + std::string file_line_col() const { + if (absl::StrContains(file, "?")) { + return file; + } + return absl::StrCat(file, ":", line, ":", col); + } }; - // Add function name and file location to symbol table. - void AddEntry(std::string_view func, std::string_view file_line_col) { - entries_.push_back({std::string(func), std::string(file_line_col)}); - } - - private: std::vector entries_; }; diff --git a/centipede/symbol_table_test.cc b/centipede/symbol_table_test.cc index 35b661750..0f9fea4e5 100644 --- a/centipede/symbol_table_test.cc +++ b/centipede/symbol_table_test.cc @@ -41,5 +41,21 @@ TEST(SymbolTableTest, SerializesAndDeserializesCorrectly) { EXPECT_EQ(input, output_stream.str()); } +TEST(SymbolTableTest, SerializesAndDeserializesCorrectlyWithUnknownFile) { + std::string input = + R"(? + ? + +)"; + std::istringstream input_stream(input); + SymbolTable symbol_table; + + symbol_table.ReadFromLLVMSymbolizer(input_stream); + + std::ostringstream output_stream; + symbol_table.WriteToLLVMSymbolizer(output_stream); + EXPECT_EQ(input, output_stream.str()); +} + } // namespace } // namespace centipede