llvm/lldb/source/Target/TraceDumper.cpp

//===-- TraceDumper.cpp ---------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "lldb/Target/TraceDumper.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include <optional>

usingnamespacelldb;
usingnamespacelldb_private;
usingnamespacellvm;

/// \return
///   The given string or \b std::nullopt if it's empty.
static std::optional<const char *> ToOptionalString(const char *s) {}

static const char *GetModuleName(const SymbolContext &sc) {}

/// \return
///   The module name (basename if the module is a file, or the actual name if
///   it's a virtual module), or \b nullptr if no name nor module was found.
static const char *GetModuleName(const TraceDumper::TraceItem &item) {}

// This custom LineEntry validator is neded because some line_entries have
// 0 as line, which is meaningless. Notice that LineEntry::IsValid only
// checks that line is not LLDB_INVALID_LINE_NUMBER, i.e. UINT32_MAX.
static bool IsLineEntryValid(const LineEntry &line_entry) {}

/// \return
///     \b true if the provided line entries match line, column and source file.
///     This function assumes that the line entries are valid.
static bool FileLineAndColumnMatches(const LineEntry &a, const LineEntry &b) {}

/// Compare the symbol contexts of the provided \a SymbolInfo
/// objects.
///
/// \return
///     \a true if both instructions belong to the same scope level analized
///     in the following order:
///       - module
///       - symbol
///       - function
///       - inlined function
///       - source line info
static bool
IsSameInstructionSymbolContext(const TraceDumper::SymbolInfo &prev_insn,
                               const TraceDumper::SymbolInfo &insn,
                               bool check_source_line_info = true) {}

class OutputWriterCLI : public TraceDumper::OutputWriter {};

class OutputWriterJSON : public TraceDumper::OutputWriter {};

static std::unique_ptr<TraceDumper::OutputWriter>
CreateWriter(Stream &s, const TraceDumperOptions &options, Thread &thread) {}

TraceDumper::TraceDumper(lldb::TraceCursorSP cursor_sp, Stream &s,
                         const TraceDumperOptions &options)
    :{}

TraceDumper::TraceItem TraceDumper::CreatRawTraceItem() {}

/// Find the symbol context for the given address reusing the previous
/// instruction's symbol context when possible.
static SymbolContext
CalculateSymbolContext(const Address &address,
                       const SymbolContext &prev_symbol_context) {}

/// Find the disassembler for the given address reusing the previous
/// instruction's disassembler when possible.
static std::tuple<DisassemblerSP, InstructionSP>
CalculateDisass(const TraceDumper::SymbolInfo &symbol_info,
                const TraceDumper::SymbolInfo &prev_symbol_info,
                const ExecutionContext &exe_ctx) {}

static TraceDumper::SymbolInfo
CalculateSymbolInfo(const ExecutionContext &exe_ctx, lldb::addr_t load_address,
                    const TraceDumper::SymbolInfo &prev_symbol_info) {}

std::optional<lldb::user_id_t> TraceDumper::DumpInstructions(size_t count) {}

void TraceDumper::FunctionCall::TracedSegment::AppendInsn(
    const TraceCursorSP &cursor_sp,
    const TraceDumper::SymbolInfo &symbol_info) {}

lldb::user_id_t
TraceDumper::FunctionCall::TracedSegment::GetFirstInstructionID() const {}

lldb::user_id_t
TraceDumper::FunctionCall::TracedSegment::GetLastInstructionID() const {}

void TraceDumper::FunctionCall::TracedSegment::IfNestedCall(
    std::function<void(const FunctionCall &function_call)> callback) const {}

const TraceDumper::FunctionCall &
TraceDumper::FunctionCall::TracedSegment::GetOwningCall() const {}

TraceDumper::FunctionCall &
TraceDumper::FunctionCall::TracedSegment::CreateNestedCall(
    const TraceCursorSP &cursor_sp,
    const TraceDumper::SymbolInfo &symbol_info) {}

const TraceDumper::SymbolInfo &
TraceDumper::FunctionCall::TracedSegment::GetFirstInstructionSymbolInfo()
    const {}

const TraceDumper::SymbolInfo &
TraceDumper::FunctionCall::TracedSegment::GetLastInstructionSymbolInfo() const {}

const TraceDumper::FunctionCall &
TraceDumper::FunctionCall::UntracedPrefixSegment::GetNestedCall() const {}

TraceDumper::FunctionCall::FunctionCall(
    const TraceCursorSP &cursor_sp,
    const TraceDumper::SymbolInfo &symbol_info) {}

void TraceDumper::FunctionCall::AppendSegment(
    const TraceCursorSP &cursor_sp,
    const TraceDumper::SymbolInfo &symbol_info) {}

const TraceDumper::SymbolInfo &
TraceDumper::FunctionCall::GetSymbolInfo() const {}

bool TraceDumper::FunctionCall::IsError() const {}

const std::deque<TraceDumper::FunctionCall::TracedSegment> &
TraceDumper::FunctionCall::GetTracedSegments() const {}

TraceDumper::FunctionCall::TracedSegment &
TraceDumper::FunctionCall::GetLastTracedSegment() {}

const std::optional<TraceDumper::FunctionCall::UntracedPrefixSegment> &
TraceDumper::FunctionCall::GetUntracedPrefixSegment() const {}

void TraceDumper::FunctionCall::SetUntracedPrefixSegment(
    TraceDumper::FunctionCallUP &&nested_call) {}

TraceDumper::FunctionCall *TraceDumper::FunctionCall::GetParentCall() const {}

void TraceDumper::FunctionCall::SetParentCall(
    TraceDumper::FunctionCall &parent_call) {}

/// Given an instruction that happens after a return, find the ancestor function
/// call that owns it. If this ancestor doesn't exist, create a new ancestor and
/// make it the root of the tree.
///
/// \param[in] last_function_call
///   The function call that performs the return.
///
/// \param[in] symbol_info
///   The symbol information of the instruction after the return.
///
/// \param[in] cursor_sp
///   The cursor pointing to the instruction after the return.
///
/// \param[in,out] roots
///   The object owning the roots. It might be modified if a new root needs to
///   be created.
///
/// \return
///   A reference to the function call that owns the new instruction
static TraceDumper::FunctionCall &AppendReturnedInstructionToFunctionCallForest(
    TraceDumper::FunctionCall &last_function_call,
    const TraceDumper::SymbolInfo &symbol_info, const TraceCursorSP &cursor_sp,
    std::vector<TraceDumper::FunctionCallUP> &roots) {}

/// Append an instruction to a function call forest. The new instruction might
/// be appended to the current segment, to a new nest call, or return to an
/// ancestor call.
///
/// \param[in] exe_ctx
///   The exeuction context of the traced thread.
///
/// \param[in] last_function_call
///   The chronologically most recent function call before the new instruction.
///
/// \param[in] prev_symbol_info
///   The symbol information of the previous instruction in the trace.
///
/// \param[in] symbol_info
///   The symbol information of the new instruction.
///
/// \param[in] cursor_sp
///   The cursor pointing to the new instruction.
///
/// \param[in,out] roots
///   The object owning the roots. It might be modified if a new root needs to
///   be created.
///
/// \return
///   A reference to the function call that owns the new instruction.
static TraceDumper::FunctionCall &AppendInstructionToFunctionCallForest(
    const ExecutionContext &exe_ctx,
    TraceDumper::FunctionCall *last_function_call,
    const TraceDumper::SymbolInfo &prev_symbol_info,
    const TraceDumper::SymbolInfo &symbol_info, const TraceCursorSP &cursor_sp,
    std::vector<TraceDumper::FunctionCallUP> &roots) {}

/// Append an error to a function call forest. The new error might be appended
/// to the current segment if it contains errors or will create a new root.
///
/// \param[in] last_function_call
///   The chronologically most recent function call before the new error.
///
/// \param[in] cursor_sp
///   The cursor pointing to the new error.
///
/// \param[in,out] roots
///   The object owning the roots. It might be modified if a new root needs to
///   be created.
///
/// \return
///   A reference to the function call that owns the new error.
TraceDumper::FunctionCall &AppendErrorToFunctionCallForest(
    TraceDumper::FunctionCall *last_function_call, TraceCursorSP &cursor_sp,
    std::vector<TraceDumper::FunctionCallUP> &roots) {}

static std::vector<TraceDumper::FunctionCallUP>
CreateFunctionCallForest(TraceCursorSP &cursor_sp,
                         const ExecutionContext &exe_ctx) {}

void TraceDumper::DumpFunctionCalls() {}