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

DWARF processing fixes #224

Merged
merged 1 commit into from
Aug 16, 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
44 changes: 36 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ endfunction()
function (build_gcov)
add_subdirectory(third_party/abseil)
add_subdirectory(third_party/glog)
add_subdirectory(third_party/googletest)

add_custom_target(exclude_extlib_tests ALL
COMMAND rm -f ${gtest_BINARY_DIR}/CTestTestfile.cmake
COMMAND rm -f ${gmock_BINARY_DIR}/CTestTestfile.cmake
COMMAND rm -f ${googletest-distribution_BINARY_DIR}/CTestTestfile.cmake
COMMAND rm -f ${glog_BINARY_DIR}/CTestTestfile.cmake
COMMAND rm -f ${absl_BINARY_DIR}/CTestTestfile.cmake)

Expand All @@ -31,6 +35,8 @@ function (build_gcov)
third_party/abseil
third_party/perf_data_converter/src
third_party/perf_data_converter/src/quipper
third_party/googletest/googletest/include
third_party/googletest/googlemock/include
util
${PROJECT_BINARY_DIR}
${PROJECT_BINARY_DIR}/third_party/glog
Expand All @@ -39,23 +45,26 @@ function (build_gcov)
find_library (LIBELF_LIBRARIES NAMES elf REQUIRED)
find_library (LIBCRYPTO_LIBRARIES NAMES crypto REQUIRED)

add_library(addr2line_lib OBJECT
legacy_addr2line.cc
util/symbolize/addr2line_inlinestack.cc
util/symbolize/bytereader.cc
util/symbolize/functioninfo.cc
util/symbolize/dwarf2reader.cc
util/symbolize/dwarf3ranges.cc
util/symbolize/elf_reader.cc
util/symbolize/index_helper.cc
)

add_library(create_gcov_lib OBJECT
create_gcov.cc
gcov.cc
instruction_map.cc
legacy_addr2line.cc
profile.cc
profile_creator.cc
profile_writer.cc
sample_reader.cc
symbol_map.cc
util/symbolize/addr2line_inlinestack.cc
util/symbolize/bytereader.cc
util/symbolize/functioninfo.cc
util/symbolize/dwarf2reader.cc
util/symbolize/dwarf3ranges.cc
util/symbolize/elf_reader.cc
util/symbolize/index_helper.cc
)
target_link_libraries(create_gcov_lib perf_proto)

Expand Down Expand Up @@ -94,6 +103,7 @@ function (build_gcov)
absl::flags
absl::flags_parse
create_gcov_lib
addr2line_lib
glog
quipper_perf
)
Expand Down Expand Up @@ -136,6 +146,24 @@ function (build_gcov)
dump_gcov_lib
glog)

add_executable(addr2line_test addr2line_test.cc)
target_link_libraries(addr2line_test
absl::base
gtest
gtest_main
absl::flags
absl::flags_parse
addr2line_lib
glog
quipper_perf)
add_test(NAME addr2line_test COMMAND addr2line_test)

add_custom_command(PRE_BUILD
OUTPUT prepare_cmds
COMMAND ln -s -f ${CMAKE_HOME_DIRECTORY}/testdata)
add_custom_target(prepare ALL
DEPENDS prepare_cmds)

endfunction()

function (build_llvm)
Expand Down
18 changes: 18 additions & 0 deletions addr2line_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "addr2line.h"
#include "third_party/abseil/absl/strings/str_cat.h"
#include "util/testing/status_matchers.h"

namespace {

using ::devtools_crosstool_autofdo::Addr2line;

TEST(Addr2lineTest, Dwarf2Dwarf5Binary) {
const std::string binary =
absl::StrCat(::testing::SrcDir(),
"/testdata/"
"dwarf2_dwarf5.bin");

Addr2line* addr2line = Addr2line::Create(binary);
EXPECT_TRUE(addr2line != NULL);
}
} // namespace
15 changes: 8 additions & 7 deletions legacy_addr2line.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,27 +105,28 @@ bool Google3Addr2line::Prepare() {
size_t debug_info_size = 0;
size_t debug_addr_size = 0;
size_t debug_ranges_size = 0;
size_t debug_rnglists_size = 0;
const char *debug_info_data = NULL;
const char *debug_addr_data = NULL;
const char *debug_ranges_data = NULL;
const char *debug_rnglists_data = NULL;
bool is_rnglists_section = false;
GetSection(sections, ".debug_info", &debug_info_data, &debug_info_size);
if (debug_info_data == NULL)
LOG(WARNING) << "File '" << binary_name_ << "' does not have .debug_info section.";
GetSection(sections, ".debug_addr", &debug_addr_data, &debug_addr_size);
GetSection(sections, ".debug_ranges", &debug_ranges_data, &debug_ranges_size);
if (debug_ranges_data == NULL) {
GetSection(sections, ".debug_rnglists", &debug_ranges_data, &debug_ranges_size);
if (debug_ranges_data != NULL)
is_rnglists_section = true;
else
LOG(WARNING) << "File '" << binary_name_ << "' does not have .debug_ranges nor .debug_rnglists sections.";
GetSection(sections, ".debug_rnglists", &debug_rnglists_data, &debug_rnglists_size);

if (debug_ranges_data == NULL && debug_rnglists_data == NULL) {
LOG(WARNING) << "File '" << binary_name_ << "' does not have .debug_ranges nor .debug_rnglists sections.";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we can proceed if both of them are not available for newer versions of dwarf. Should this be a fatal error instead (based on the dwarf version)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible that the binary has no address ranges in its dwarf info. If we attempt to use address ranges later, we will assert at that time (in dwarf3ranges.cc).

}

AddressRangeList debug_ranges(debug_ranges_data,
debug_ranges_size,
debug_rnglists_data,
debug_rnglists_size,
&reader,
is_rnglists_section,
debug_addr_data,
debug_addr_size);
inline_stack_handler_ = new InlineStackHandler(
Expand Down
Binary file added testdata/dwarf2_dwarf5.bin
Binary file not shown.
16 changes: 9 additions & 7 deletions util/symbolize/addr2line_inlinestack.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ bool InlineStackHandler::StartCompilationUnit(uint64 offset,
uint8 /*address_size*/,
uint8 /*offset_size*/,
uint64 /*cu_length*/,
uint8 /*dwarf_version*/) {
uint8 dwarf_version) {
CHECK(subprogram_stack_.empty());
compilation_unit_offset_ = offset;
compilation_unit_base_ = 0;
Expand All @@ -109,6 +109,7 @@ bool InlineStackHandler::StartCompilationUnit(uint64 offset,
input_file_index_ = 0;
subprograms_by_offset_maps_.push_back(new SubprogramsByOffsetMap);
}
dwarf_version_ = dwarf_version;
return true;
}

Expand Down Expand Up @@ -348,13 +349,14 @@ void InlineStackHandler::ProcessAttributeUnsigned(
case DW_AT_ranges: {
CHECK_EQ(0, subprogram_stack_.back()->address_ranges()->size());
AddressRangeList::RangeList ranges;
if (form == DW_FORM_sec_offset) {
address_ranges_->ReadRangeList(data, compilation_unit_base_, &ranges);

if (form == DW_FORM_sec_offset || form == DW_FORM_data4 || form == DW_FORM_data8) {
address_ranges_->ReadRangeList(data, compilation_unit_base_, &ranges, dwarf_version_);
}
else {
CHECK(form == DW_FORM_rnglistx);
uint64 address_ = address_ranges_->GetRngListsElementOffsetByIndex(ranges_base_, data);
address_ranges_->ReadDwarfRngListwithOffsetArray(address_, compilation_unit_base_, &ranges, addr_base_, ranges_base_);
CHECK(form == DW_FORM_rnglistx);
uint64 address_ = address_ranges_->GetRngListsElementOffsetByIndex(ranges_base_, data);
address_ranges_->ReadDwarfRngListwithOffsetArray(address_, compilation_unit_base_, &ranges, addr_base_, ranges_base_);
}

if (subprogram_stack_.size() == 1) {
Expand Down Expand Up @@ -440,7 +442,7 @@ void InlineStackHandler::ProcessAttributeUnsigned(
str_offset_base_ = data;
break;
case DW_AT_ranges:
CHECK(form == DW_FORM_sec_offset);
CHECK(form == DW_FORM_sec_offset || form == DW_FORM_data4 || form == DW_FORM_data8);
FALLTHROUGH_INTENDED;
case DW_AT_GNU_ranges_base:
case DW_AT_rnglists_base:
Expand Down
1 change: 1 addition & 0 deletions util/symbolize/addr2line_inlinestack.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ class InlineStackHandler: public Dwarf2Handler {
int overlap_count_;
bool have_two_level_line_tables_;
bool subprogram_added_by_cu_;
uint8 dwarf_version_;

DISALLOW_COPY_AND_ASSIGN(InlineStackHandler);
};
Expand Down
10 changes: 6 additions & 4 deletions util/symbolize/dwarf2reader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1017,15 +1017,17 @@ void CompilationUnit::ProcessSplitDwarf() {
auto iter = sections.find(".debug_rnglists");
size_t debug_ranges_size = 0;
const char *debug_ranges_data = NULL;
size_t debug_rnglist_size = 0;
const char *debug_rnglist_data = NULL;
if (iter != sections.end()) {
debug_ranges_data = iter->second.first;
debug_ranges_size = iter->second.second;
const bool is_rnglists_section = true;
debug_rnglist_data = iter->second.first;
debug_rnglist_size = iter->second.second;
AddressRangeList *debug_ranges =
new AddressRangeList(debug_ranges_data,
debug_ranges_size,
debug_rnglist_data,
debug_rnglist_size,
&reader,
is_rnglists_section,
addr_buffer_,
addr_buffer_length_);
InlineStackHandler *inlinestackhandler = dynamic_cast<InlineStackHandler*>(handler_);
Expand Down
Loading