From aef7908f6eb060b928f4aa820e4ba5e316ee5e00 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Wed, 3 Oct 2018 12:29:33 +0000 Subject: [PATCH] Pull FixupBreakpointPCAsNeeded into base class Summary: This function existed (with identical code) in both NativeProcessLinux and NativeProcessNetBSD, and it is likely that it would be useful to any future implementation of NativeProcessProtocol. Therefore I move it to the base class. Reviewers: krytarowski Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D52719 llvm-svn: 343683 --- .../lldb/Host/common/NativeProcessProtocol.h | 5 ++ lldb/source/Host/common/NativeProcessProtocol.cpp | 62 ++++++++++++++++++ .../Plugins/Process/Linux/NativeProcessLinux.cpp | 76 +--------------------- .../Plugins/Process/Linux/NativeProcessLinux.h | 2 - .../Plugins/Process/NetBSD/NativeProcessNetBSD.cpp | 75 --------------------- .../Plugins/Process/NetBSD/NativeProcessNetBSD.h | 1 - 6 files changed, 68 insertions(+), 153 deletions(-) diff --git a/lldb/include/lldb/Host/common/NativeProcessProtocol.h b/lldb/include/lldb/Host/common/NativeProcessProtocol.h index 7577524..0e0ede2 100644 --- a/lldb/include/lldb/Host/common/NativeProcessProtocol.h +++ b/lldb/include/lldb/Host/common/NativeProcessProtocol.h @@ -457,6 +457,11 @@ protected: /// PC, this offset will be the size of the breakpoint opcode. virtual size_t GetSoftwareBreakpointPCOffset(); + // Adjust the thread's PC after hitting a software breakpoint. On + // architectures where the PC points after the breakpoint instruction, this + // resets it to point to the breakpoint itself. + void FixupBreakpointPCAsNeeded(NativeThreadProtocol &thread); + // ----------------------------------------------------------- /// Notify the delegate that an exec occurred. /// diff --git a/lldb/source/Host/common/NativeProcessProtocol.cpp b/lldb/source/Host/common/NativeProcessProtocol.cpp index ef063d5..5d0eff7 100644 --- a/lldb/source/Host/common/NativeProcessProtocol.cpp +++ b/lldb/source/Host/common/NativeProcessProtocol.cpp @@ -432,6 +432,68 @@ size_t NativeProcessProtocol::GetSoftwareBreakpointPCOffset() { } } +void NativeProcessProtocol::FixupBreakpointPCAsNeeded( + NativeThreadProtocol &thread) { + Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS); + + Status error; + + // Find out the size of a breakpoint (might depend on where we are in the + // code). + NativeRegisterContext &context = thread.GetRegisterContext(); + + uint32_t breakpoint_size = GetSoftwareBreakpointPCOffset(); + LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size); + if (breakpoint_size == 0) + return; + + // First try probing for a breakpoint at a software breakpoint location: PC - + // breakpoint size. + const lldb::addr_t initial_pc_addr = context.GetPCfromBreakpointLocation(); + lldb::addr_t breakpoint_addr = initial_pc_addr; + // Do not allow breakpoint probe to wrap around. + if (breakpoint_addr >= breakpoint_size) + breakpoint_addr -= breakpoint_size; + + // Check if we stopped because of a breakpoint. + NativeBreakpointSP breakpoint_sp; + error = m_breakpoint_list.GetBreakpoint(breakpoint_addr, breakpoint_sp); + if (!error.Success() || !breakpoint_sp) { + // We didn't find one at a software probe location. Nothing to do. + LLDB_LOG(log, + "pid {0} no lldb breakpoint found at current pc with " + "adjustment: {1}", + GetID(), breakpoint_addr); + return; + } + + // If the breakpoint is not a software breakpoint, nothing to do. + if (!breakpoint_sp->IsSoftwareBreakpoint()) { + LLDB_LOG( + log, + "pid {0} breakpoint found at {1:x}, not software, nothing to adjust", + GetID(), breakpoint_addr); + return; + } + + // + // We have a software breakpoint and need to adjust the PC. + // + + // Change the program counter. + LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(), + thread.GetID(), initial_pc_addr, breakpoint_addr); + + error = context.SetPC(breakpoint_addr); + if (error.Fail()) { + // This can happen in case the process was killed between the time we read + // the PC and when we are updating it. There's nothing better to do than to + // swallow the error. + LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(), + thread.GetID(), error); + } +} + Status NativeProcessProtocol::RemoveBreakpoint(lldb::addr_t addr, bool hardware) { if (hardware) diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp index f1d3bec..4f36fba 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -759,9 +759,7 @@ void NativeProcessLinux::MonitorBreakpoint(NativeThreadLinux &thread) { // Mark the thread as stopped at breakpoint. thread.SetStoppedByBreakpoint(); - Status error = FixupBreakpointPCAsNeeded(thread); - if (error.Fail()) - LLDB_LOG(log, "pid = {0} fixup: {1}", thread.GetID(), error); + FixupBreakpointPCAsNeeded(thread); if (m_threads_stepping_with_breakpoint.find(thread.GetID()) != m_threads_stepping_with_breakpoint.end()) @@ -1719,78 +1717,6 @@ NativeThreadLinux &NativeProcessLinux::AddThread(lldb::tid_t thread_id) { return static_cast(*m_threads.back()); } -Status -NativeProcessLinux::FixupBreakpointPCAsNeeded(NativeThreadLinux &thread) { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS)); - - Status error; - - // Find out the size of a breakpoint (might depend on where we are in the - // code). - NativeRegisterContext &context = thread.GetRegisterContext(); - - uint32_t breakpoint_size = GetSoftwareBreakpointPCOffset(); - LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size); - - // First try probing for a breakpoint at a software breakpoint location: PC - - // breakpoint size. - const lldb::addr_t initial_pc_addr = context.GetPCfromBreakpointLocation(); - lldb::addr_t breakpoint_addr = initial_pc_addr; - if (breakpoint_size > 0) { - // Do not allow breakpoint probe to wrap around. - if (breakpoint_addr >= breakpoint_size) - breakpoint_addr -= breakpoint_size; - } - - // Check if we stopped because of a breakpoint. - NativeBreakpointSP breakpoint_sp; - error = m_breakpoint_list.GetBreakpoint(breakpoint_addr, breakpoint_sp); - if (!error.Success() || !breakpoint_sp) { - // We didn't find one at a software probe location. Nothing to do. - LLDB_LOG(log, - "pid {0} no lldb breakpoint found at current pc with " - "adjustment: {1}", - GetID(), breakpoint_addr); - return Status(); - } - - // If the breakpoint is not a software breakpoint, nothing to do. - if (!breakpoint_sp->IsSoftwareBreakpoint()) { - LLDB_LOG( - log, - "pid {0} breakpoint found at {1:x}, not software, nothing to adjust", - GetID(), breakpoint_addr); - return Status(); - } - - // - // We have a software breakpoint and need to adjust the PC. - // - - // Sanity check. - if (breakpoint_size == 0) { - // Nothing to do! How did we get here? - LLDB_LOG(log, - "pid {0} breakpoint found at {1:x}, it is software, but the " - "size is zero, nothing to do (unexpected)", - GetID(), breakpoint_addr); - return Status(); - } - - // Change the program counter. - LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(), - thread.GetID(), initial_pc_addr, breakpoint_addr); - - error = context.SetPC(breakpoint_addr); - if (error.Fail()) { - LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(), - thread.GetID(), error); - return error; - } - - return error; -} - Status NativeProcessLinux::GetLoadedModuleFileSpec(const char *module_path, FileSpec &file_spec) { Status error = PopulateMemoryRegionCache(); diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h index 5147c36..69f2b52 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h @@ -182,8 +182,6 @@ private: NativeThreadLinux &AddThread(lldb::tid_t thread_id); - Status FixupBreakpointPCAsNeeded(NativeThreadLinux &thread); - /// Writes a siginfo_t structure corresponding to the given thread ID to the /// memory region pointed to by @p siginfo. Status GetSignalInfo(lldb::tid_t tid, void *siginfo); diff --git a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp index 6326691..0157dac 100644 --- a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp +++ b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp @@ -322,81 +322,6 @@ Status NativeProcessNetBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr, return error; } -Status -NativeProcessNetBSD::FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread) { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS)); - Status error; - // Find out the size of a breakpoint (might depend on where we are in the - // code). - NativeRegisterContext& context = thread.GetRegisterContext(); - uint32_t breakpoint_size = GetSoftwareBreakpointPCOffset(); - LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size); - - // First try probing for a breakpoint at a software breakpoint location: PC - - // breakpoint size. - const lldb::addr_t initial_pc_addr = - context.GetPCfromBreakpointLocation(); - lldb::addr_t breakpoint_addr = initial_pc_addr; - if (breakpoint_size > 0) { - // Do not allow breakpoint probe to wrap around. - if (breakpoint_addr >= breakpoint_size) - breakpoint_addr -= breakpoint_size; - } - // Check if we stopped because of a breakpoint. - NativeBreakpointSP breakpoint_sp; - error = m_breakpoint_list.GetBreakpoint(breakpoint_addr, breakpoint_sp); - if (!error.Success() || !breakpoint_sp) { - // We didn't find one at a software probe location. Nothing to do. - LLDB_LOG(log, - "pid {0} no lldb breakpoint found at current pc with " - "adjustment: {1}", - GetID(), breakpoint_addr); - return Status(); - } - // If the breakpoint is not a software breakpoint, nothing to do. - if (!breakpoint_sp->IsSoftwareBreakpoint()) { - LLDB_LOG( - log, - "pid {0} breakpoint found at {1:x}, not software, nothing to adjust", - GetID(), breakpoint_addr); - return Status(); - } - // - // We have a software breakpoint and need to adjust the PC. - // - // Sanity check. - if (breakpoint_size == 0) { - // Nothing to do! How did we get here? - LLDB_LOG(log, - "pid {0} breakpoint found at {1:x}, it is software, but the " - "size is zero, nothing to do (unexpected)", - GetID(), breakpoint_addr); - return Status(); - } - // - // We have a software breakpoint and need to adjust the PC. - // - // Sanity check. - if (breakpoint_size == 0) { - // Nothing to do! How did we get here? - LLDB_LOG(log, - "pid {0} breakpoint found at {1:x}, it is software, but the " - "size is zero, nothing to do (unexpected)", - GetID(), breakpoint_addr); - return Status(); - } - // Change the program counter. - LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(), - thread.GetID(), initial_pc_addr, breakpoint_addr); - error = context.SetPC(breakpoint_addr); - if (error.Fail()) { - LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(), - thread.GetID(), error); - return error; - } - return error; -} - Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); LLDB_LOG(log, "pid {0}", GetID()); diff --git a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h index 64d85b2..a3f1c4c 100644 --- a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h +++ b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h @@ -112,7 +112,6 @@ private: void MonitorSIGTRAP(lldb::pid_t pid); void MonitorSignal(lldb::pid_t pid, int signal); - Status FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread); Status PopulateMemoryRegionCache(); void SigchldHandler(); -- 2.7.4