Summary: Update StackFrame::GetSymbolContext to mirror the logic in RegisterContextLLDB::InitializeNonZerothFrame that knows not to do the pc decrement when the given frame is a signal trap handler frame or the parent of one, because the pc may not follow a call in these frames. Accomplish this by adding a behaves_like_zeroth_frame field to lldb_private::StackFrame, set to true for the zeroth frame, for signal handler frames, and for parents of signal handler frames. Also add logic to propagate the signal handler flag from UnwindPlan to the FrameType on the RegisterContextLLDB it generates, and factor out a helper to resolve symbol and address range for an Address now that we need to invoke it in four places. Reviewers: jasonmolenda, clayborg, jfb Reviewed By: jasonmolenda Subscribers: labath, dexonsmith, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D64993 llvm-svn: 367691
69 lines
2.1 KiB
C++
69 lines
2.1 KiB
C++
//===-- HistoryUnwind.cpp ---------------------------------------*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/lldb-private.h"
|
|
|
|
#include "Plugins/Process/Utility/HistoryUnwind.h"
|
|
#include "Plugins/Process/Utility/RegisterContextHistory.h"
|
|
|
|
#include "lldb/Target/Process.h"
|
|
#include "lldb/Target/StackFrame.h"
|
|
#include "lldb/Target/Target.h"
|
|
#include "lldb/Target/Thread.h"
|
|
|
|
#include <memory>
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
// Constructor
|
|
|
|
HistoryUnwind::HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs)
|
|
: Unwind(thread), m_pcs(pcs) {}
|
|
|
|
// Destructor
|
|
|
|
HistoryUnwind::~HistoryUnwind() {}
|
|
|
|
void HistoryUnwind::DoClear() {
|
|
std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
|
|
m_pcs.clear();
|
|
}
|
|
|
|
lldb::RegisterContextSP
|
|
HistoryUnwind::DoCreateRegisterContextForFrame(StackFrame *frame) {
|
|
RegisterContextSP rctx;
|
|
if (frame) {
|
|
addr_t pc = frame->GetFrameCodeAddress().GetLoadAddress(
|
|
&frame->GetThread()->GetProcess()->GetTarget());
|
|
if (pc != LLDB_INVALID_ADDRESS) {
|
|
rctx = std::make_shared<RegisterContextHistory>(
|
|
*frame->GetThread().get(), frame->GetConcreteFrameIndex(),
|
|
frame->GetThread()->GetProcess()->GetAddressByteSize(), pc);
|
|
}
|
|
}
|
|
return rctx;
|
|
}
|
|
|
|
bool HistoryUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
|
|
lldb::addr_t &pc,
|
|
bool &behaves_like_zeroth_frame) {
|
|
// FIXME do not throw away the lock after we acquire it..
|
|
std::unique_lock<std::recursive_mutex> guard(m_unwind_mutex);
|
|
guard.unlock();
|
|
if (frame_idx < m_pcs.size()) {
|
|
cfa = frame_idx;
|
|
pc = m_pcs[frame_idx];
|
|
behaves_like_zeroth_frame = (frame_idx == 0);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
uint32_t HistoryUnwind::DoGetFrameCount() { return m_pcs.size(); }
|