| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/developer/debug/zxdb/console/format_location.h" |
| |
| #include <gtest/gtest.h> |
| |
| #include "src/developer/debug/zxdb/client/session.h" |
| #include "src/developer/debug/zxdb/console/console_context.h" |
| #include "src/developer/debug/zxdb/symbols/elf_symbol.h" |
| #include "src/developer/debug/zxdb/symbols/function.h" |
| #include "src/developer/debug/zxdb/symbols/location.h" |
| #include "src/developer/debug/zxdb/symbols/process_symbols_test_setup.h" |
| #include "src/developer/debug/zxdb/symbols/symbol_context.h" |
| |
| namespace zxdb { |
| |
| TEST(FormatLocation, FormatLocation_Function) { |
| SymbolContext symbol_context = SymbolContext::ForRelativeAddresses(); |
| |
| FormatLocationOptions no_addrs_no_params; |
| no_addrs_no_params.always_show_addresses = false; |
| no_addrs_no_params.show_file_line = true; |
| EXPECT_EQ("<invalid address>", FormatLocation(Location(), no_addrs_no_params).AsString()); |
| |
| // Address-only location. |
| EXPECT_EQ( |
| "0x12345", |
| FormatLocation(Location(Location::State::kAddress, 0x12345), no_addrs_no_params).AsString()); |
| |
| // Function-only location. |
| fxl::RefPtr<Function> function(fxl::MakeRefCounted<Function>(DwarfTag::kSubprogram)); |
| function->set_assigned_name("Func"); |
| function->set_code_ranges(AddressRanges(AddressRange(0x1200, 0x1300))); |
| EXPECT_EQ( |
| "Func() + 0x34 (no line info)", |
| FormatLocation(Location(0x1234, FileLine(), 0, symbol_context, function), no_addrs_no_params) |
| .AsString()); |
| |
| // Same as above but location is before the function address (probably something is corrupt). It |
| // should omit the offset. |
| EXPECT_EQ("Func()", FormatLocation(Location(0x1100, FileLine(), 0, symbol_context, function), |
| no_addrs_no_params) |
| .AsString()); |
| |
| // File/line present but not shown. |
| FormatLocationOptions no_file_line; |
| no_file_line.always_show_addresses = false; |
| no_file_line.show_file_line = false; |
| Location loc(0x1234, FileLine("/path/foo.cc", 21), 0, symbol_context, function); |
| EXPECT_EQ("Func() + 0x34", FormatLocation(loc, no_file_line).AsString()); |
| |
| // File/line not shown and address exactly matches the symbol (the offset should be omitted). |
| Location func_loc(0x1234, FileLine("/path/foo.cc", 21), 0, symbol_context, function); |
| EXPECT_EQ("Func() + 0x34", FormatLocation(func_loc, no_file_line).AsString()); |
| |
| // File/line-only location. |
| EXPECT_EQ("0x1234 • /path/foo.cc:21", |
| FormatLocation(Location(0x1234, FileLine("/path/foo.cc", 21), 0, symbol_context), |
| no_addrs_no_params) |
| .AsString()); |
| |
| // Full location. |
| FormatLocationOptions always_addr; |
| always_addr.always_show_addresses = true; |
| always_addr.show_file_line = true; |
| EXPECT_EQ("0x1234, Func() • /path/foo.cc:21", FormatLocation(loc, always_addr).AsString()); |
| EXPECT_EQ("Func() • /path/foo.cc:21", FormatLocation(loc, no_addrs_no_params).AsString()); |
| |
| // Test with file shortening. This target has no files so everything is unique and will be |
| // shortened. |
| ProcessSymbolsTestSetup setup; |
| FormatLocationOptions with_target; |
| with_target.show_file_line = true; |
| with_target.target_symbols = &setup.target(); |
| EXPECT_EQ("Func() • foo.cc:21", FormatLocation(loc, with_target).AsString()); |
| |
| // Use the same parameters but force showing the whole path. |
| with_target.show_file_path = true; |
| EXPECT_EQ("Func() • /path/foo.cc:21", FormatLocation(loc, with_target).AsString()); |
| } |
| |
| TEST(FormatLocation, FormatLocation_ELF) { |
| SymbolContext symbol_context = SymbolContext::ForRelativeAddresses(); |
| |
| FormatLocationOptions options; |
| options.always_show_addresses = false; |
| |
| // Address exactly at the beginning of the ELF symbol. |
| constexpr uint64_t kFunctionAddress = 0x1000; |
| fxl::RefPtr<ElfSymbol> elf_symbol(fxl::MakeRefCounted<ElfSymbol>( |
| fxl::WeakPtr<ModuleSymbols>(), |
| ElfSymbolRecord(ElfSymbolType::kPlt, kFunctionAddress, 0, "memset"))); |
| EXPECT_EQ( |
| "$plt(memset)", |
| FormatLocation(Location(kFunctionAddress, FileLine(), 0, symbol_context, elf_symbol), options) |
| .AsString()); |
| |
| // Address with an offset from the beginning. |
| EXPECT_EQ("$plt(memset) + 0x6", |
| FormatLocation( |
| Location(kFunctionAddress + 6, FileLine(), 0, symbol_context, elf_symbol), options) |
| .AsString()); |
| } |
| |
| // This implicitly tests FormatFileName() also. |
| TEST(FormatLocation, FormatFileLine) { |
| FileLine fl("/path/to/foo.cc", 21); |
| EXPECT_EQ("/path/to/foo.cc:21", FormatFileLine(fl).AsString()); |
| |
| // Missing both. |
| EXPECT_EQ("?:?", FormatFileLine(FileLine()).AsString()); |
| |
| // Pass an TargetSymbols to trigger path shortening. Since the TargetSymbols has no files to |
| // match, the name will be unique and we'll get just the name part. |
| // |
| // This also tests the syntax highlighting. |
| ProcessSymbolsTestSetup setup; |
| EXPECT_EQ("kFileName \"foo.cc\", kComment \":\", kNormal \"21\"", |
| FormatFileLine(fl, &setup.target()).GetDebugString()); |
| } |
| |
| } // namespace zxdb |