Stella Stamenova 45d8134c3b [windows] LLDB shows the wrong values when register read is executed at a frame other than zero
Summary:
This is a clean version of the change suggested here: https://bugs.llvm.org/show_bug.cgi?id=37495

The main change is to follow the same pattern as non-windows targets and use an unwinder object to retrieve the register context. I also changed a couple of the comments to actually log, so that issues with unsupported scenarios can be tracked down more easily. Lastly, ClearStackFrames is implemented in the base class, so individual thread implementations don't have to override it.

Reviewers: asmith, zturner, aleksandr.urakov

Reviewed By: aleksandr.urakov

Subscribers: emaste, stella.stamenova, tatyana-krasnukha, llvm-commits

Differential Revision: https://reviews.llvm.org/D49111

llvm-svn: 336732
2018-07-10 22:05:33 +00:00

102 lines
3.1 KiB
C++

//===-- ThreadMemory.cpp ----------------------------------------------*- C++
//-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "Plugins/Process/Utility/ThreadMemory.h"
#include "Plugins/Process/Utility/RegisterContextThreadMemory.h"
#include "lldb/Target/OperatingSystem.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Unwind.h"
using namespace lldb;
using namespace lldb_private;
ThreadMemory::ThreadMemory(Process &process, tid_t tid,
const ValueObjectSP &thread_info_valobj_sp)
: Thread(process, tid), m_backing_thread_sp(),
m_thread_info_valobj_sp(thread_info_valobj_sp), m_name(), m_queue() {}
ThreadMemory::ThreadMemory(Process &process, lldb::tid_t tid,
llvm::StringRef name, llvm::StringRef queue,
lldb::addr_t register_data_addr)
: Thread(process, tid), m_backing_thread_sp(), m_thread_info_valobj_sp(),
m_name(name), m_queue(queue), m_register_data_addr(register_data_addr) {}
ThreadMemory::~ThreadMemory() { DestroyThread(); }
void ThreadMemory::WillResume(StateType resume_state) {
if (m_backing_thread_sp)
m_backing_thread_sp->WillResume(resume_state);
}
void ThreadMemory::ClearStackFrames() {
if (m_backing_thread_sp)
m_backing_thread_sp->ClearStackFrames();
Thread::ClearStackFrames();
}
RegisterContextSP ThreadMemory::GetRegisterContext() {
if (!m_reg_context_sp)
m_reg_context_sp.reset(
new RegisterContextThreadMemory(*this, m_register_data_addr));
return m_reg_context_sp;
}
RegisterContextSP
ThreadMemory::CreateRegisterContextForFrame(StackFrame *frame) {
RegisterContextSP reg_ctx_sp;
uint32_t concrete_frame_idx = 0;
if (frame)
concrete_frame_idx = frame->GetConcreteFrameIndex();
if (concrete_frame_idx == 0) {
reg_ctx_sp = GetRegisterContext();
} else {
Unwind *unwinder = GetUnwinder();
if (unwinder != nullptr)
reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
}
return reg_ctx_sp;
}
bool ThreadMemory::CalculateStopInfo() {
if (m_backing_thread_sp) {
lldb::StopInfoSP backing_stop_info_sp(
m_backing_thread_sp->GetPrivateStopInfo());
if (backing_stop_info_sp &&
backing_stop_info_sp->IsValidForOperatingSystemThread(*this)) {
backing_stop_info_sp->SetThread(shared_from_this());
SetStopInfo(backing_stop_info_sp);
return true;
}
} else {
ProcessSP process_sp(GetProcess());
if (process_sp) {
OperatingSystem *os = process_sp->GetOperatingSystem();
if (os) {
SetStopInfo(os->CreateThreadStopReason(this));
return true;
}
}
}
return false;
}
void ThreadMemory::RefreshStateAfterStop() {
if (m_backing_thread_sp)
return m_backing_thread_sp->RefreshStateAfterStop();
if (m_reg_context_sp)
m_reg_context_sp->InvalidateAllRegisters();
}