blob: 06b7edf9b29b2d11f8ba693e04c0644d13971d0b [file] [log] [blame]
// 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