llvm-project/lldb/source/Plugins/Process/minidump/MinidumpParser.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

114 lines
3.6 KiB
C
Raw Normal View History

//===-- MinidumpParser.h -----------------------------------------*- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPPARSER_H
#define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPPARSER_H
#include "MinidumpTypes.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/UUID.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/Minidump.h"
// C includes
// C++ includes
#include <cstring>
#include <unordered_map>
namespace lldb_private {
namespace minidump {
// Describes a range of memory captured in the Minidump
struct Range {
lldb::addr_t start; // virtual address of the beginning of the range
// range_ref - absolute pointer to the first byte of the range and size
llvm::ArrayRef<uint8_t> range_ref;
Range(lldb::addr_t start, llvm::ArrayRef<uint8_t> range_ref)
: start(start), range_ref(range_ref) {}
friend bool operator==(const Range &lhs, const Range &rhs) {
return lhs.start == rhs.start && lhs.range_ref == rhs.range_ref;
}
};
class MinidumpParser {
public:
static llvm::Expected<MinidumpParser>
Create(const lldb::DataBufferSP &data_buf_sp);
llvm::ArrayRef<uint8_t> GetData();
llvm::ArrayRef<uint8_t> GetStream(StreamType stream_type);
UUID GetModuleUUID(const minidump::Module *module);
llvm::ArrayRef<minidump::Thread> GetThreads();
llvm::ArrayRef<uint8_t> GetThreadContext(const LocationDescriptor &location);
llvm::ArrayRef<uint8_t> GetThreadContext(const minidump::Thread &td);
llvm::ArrayRef<uint8_t> GetThreadContextWow64(const minidump::Thread &td);
ArchSpec GetArchitecture();
const MinidumpMiscInfo *GetMiscInfo();
llvm::Optional<LinuxProcStatus> GetLinuxProcStatus();
llvm::Optional<lldb::pid_t> GetPid();
llvm::ArrayRef<minidump::Module> GetModuleList();
// There are cases in which there is more than one record in the ModuleList
// for the same module name.(e.g. when the binary has non contiguous segments)
// So this function returns a filtered module list - if it finds records that
// have the same name, it keeps the copy with the lowest load address.
std::vector<const minidump::Module *> GetFilteredModuleList();
const llvm::minidump::ExceptionStream *GetExceptionStream();
llvm::Optional<Range> FindMemoryRange(lldb::addr_t addr);
llvm::ArrayRef<uint8_t> GetMemory(lldb::addr_t addr, size_t size);
lldb/minidump: Refactor memory region computation code The goal of this refactor is to enable ProcessMinidump to take into account the loaded modules and their sections when computing the permissions of various ranges of memory, as discussed in D66638. This patch moves some of the responsibility for computing the ranges from MinidumpParser into ProcessMinidump. MinidumpParser still does the parsing, but ProcessMinidump becomes responsible for answering the actual queries about memory ranges. This will enable it (in a follow-up patch) to augment the information obtained from the parser with data obtained from actual object files. The changes in the actual code are fairly straight-forward and just involve moving code around. MinidumpParser::GetMemoryRegions is renamed to BuildMemoryRegions to emphasize that it does no caching. The only new thing is the additional bool flag returned from this function. This indicates whether the returned regions describe all memory mapped into the target process. Data obtained from /proc/maps and the MemoryInfoList stream is considered to be exhaustive. Data obtained from Memory(64)List is not. This will be used to determine whether we need to augment the data or not. This reshuffle means that it is no longer possible/easy to test some of this code via unit tests, as constructing a ProcessMinidump instance is hard. Instead, I update the unit tests to only test the parsing of the actual data, and test the answering of queries through a lit test using the "memory region" command. The patch also includes some tweaks to the MemoryRegion class to make the unit tests easier to write. Reviewers: amccarth, clayborg Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D69035
2019-10-26 06:18:51 +08:00
/// Returns a list of memory regions and a flag indicating whether the list is
/// complete (includes all regions mapped into the process memory).
std::pair<MemoryRegionInfos, bool> BuildMemoryRegions();
static llvm::StringRef GetStreamTypeAsString(StreamType stream_type);
llvm::object::MinidumpFile &GetMinidumpFile() { return *m_file; }
static MemoryRegionInfo GetMemoryRegionInfo(const MemoryRegionInfos &regions,
lldb::addr_t load_addr);
private:
MinidumpParser(lldb::DataBufferSP data_sp,
std::unique_ptr<llvm::object::MinidumpFile> file);
lldb::DataBufferSP m_data_sp;
std::unique_ptr<llvm::object::MinidumpFile> m_file;
ArchSpec m_arch;
};
} // end namespace minidump
} // end namespace lldb_private
#endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_MINIDUMPPARSER_H