diff options
Diffstat (limited to 'lldb/source')
22 files changed, 186 insertions, 99 deletions
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 6754b76bff3..04b262664e4 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -1245,7 +1245,7 @@ ValueObject::Dereference (Error &error) child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class); - if (child_clang_type && child_byte_offset) + if (child_clang_type && child_byte_size) { ConstString child_name; if (!child_name_str.empty()) diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index 05d2b0bc261..2f2d0ceee79 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -713,13 +713,9 @@ ClangExpressionDeclMap::DoMaterialize { ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index)); - ClangExpressionVariableSP entity_sp (m_found_entities.GetVariable(member_sp->GetName())); - - ClangExpressionVariableSP persistent_var_sp (persistent_vars.GetVariable(member_sp->GetName())); - - if (entity_sp) + if (m_found_entities.ContainsVariable (member_sp)) { - RegisterInfo *reg_info = entity_sp->GetRegisterInfo (); + RegisterInfo *reg_info = member_sp->GetRegisterInfo (); if (reg_info) { // This is a register variable @@ -752,34 +748,36 @@ ClangExpressionDeclMap::DoMaterialize return false; } } - else if (persistent_var_sp) + else { - if (member_sp->GetName() == m_struct_vars->m_result_name) + // No need to look for presistent variables if the name doesn't start + // with with a '$' character... + if (member_sp->GetName().AsCString ("!")[0] == '$' && persistent_vars.ContainsVariable(member_sp)) { - if (!dematerialize) - continue; - - if (log) - log->PutCString("Found result member in the struct"); - - if (result_sp_ptr) - *result_sp_ptr = member_sp; + if (member_sp->GetName() == m_struct_vars->m_result_name) + { + if (!dematerialize) + continue; + + if (log) + log->PutCString("Found result member in the struct"); + + if (result_sp_ptr) + *result_sp_ptr = member_sp; + } + + if (!DoMaterializeOnePersistentVariable (dematerialize, + exe_ctx, + member_sp, + m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset, + err)) + return false; } - - if (log) - log->Printf("Searched for persistent variable %s and found %s", member_sp->GetName().GetCString(), persistent_var_sp->GetName().GetCString()); - - if (!DoMaterializeOnePersistentVariable (dematerialize, - exe_ctx, - persistent_var_sp, - m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset, - err)) + else + { + err.SetErrorStringWithFormat("Unexpected variable %s", member_sp->GetName().GetCString()); return false; - } - else - { - err.SetErrorStringWithFormat("Unexpected variable %s", member_sp->GetName().GetCString()); - return false; + } } } diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp index 29c06bb625b..55e5534a5d8 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp +++ b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp @@ -394,7 +394,7 @@ g_exc_regnums[] = static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo)); void -RegisterContextMach_arm::Invalidate () +RegisterContextMach_arm::InvalidateAllRegisters () { InvalidateAllRegisterStates(); } diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h index 158e701f02d..3f9654c72c8 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h +++ b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h @@ -60,7 +60,7 @@ public: ~RegisterContextMach_arm(); virtual void - Invalidate (); + InvalidateAllRegisters (); virtual size_t GetRegisterCount (); diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp index fe23e7ae7b3..077a492bbf4 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp +++ b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp @@ -275,7 +275,7 @@ static RegisterInfo g_register_infos[] = static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo)); void -RegisterContextMach_i386::Invalidate () +RegisterContextMach_i386::InvalidateAllRegisters () { InvalidateAllRegisterStates(); } diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h index 20c5e3d9a2b..7a3c5dad08b 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h +++ b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h @@ -28,7 +28,7 @@ public: ~RegisterContextMach_i386(); virtual void - Invalidate (); + InvalidateAllRegisters (); virtual size_t GetRegisterCount (); diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp index 21e05267755..8b1ed79d3c7 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp +++ b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp @@ -311,7 +311,7 @@ static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterIn void -RegisterContextMach_x86_64::Invalidate () +RegisterContextMach_x86_64::InvalidateAllRegisters () { InvalidateAllRegisterStates(); } diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h index 0fc8ca5150b..316575c9aa7 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h +++ b/lldb/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h @@ -27,7 +27,7 @@ public: ~RegisterContextMach_x86_64(); virtual void - Invalidate (); + InvalidateAllRegisters (); virtual size_t GetRegisterCount (); diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp index 2f01dc6e8b8..900153f747e 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp +++ b/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp @@ -198,7 +198,7 @@ void ThreadMacOSX::RefreshStateAfterStop() { // Invalidate all registers in our register context - GetRegisterContext()->Invalidate(); + GetRegisterContext()->InvalidateIfNeeded (false); m_context->RefreshStateAfterStop(); @@ -650,7 +650,7 @@ ThreadMacOSX::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint) // Clear out all stack frames as our world just changed. ClearStackFrames(); - frame_sp->GetRegisterContext()->Invalidate(); + frame_sp->GetRegisterContext()->InvalidateIfNeeded(true); return ret; } diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index 8aadc04f1ff..b76b093f88f 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -633,7 +633,7 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame () void -RegisterContextLLDB::Invalidate () +RegisterContextLLDB::InvalidateAllRegisters () { m_frame_type = eNotAValidFrame; } diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h index 57e89a3f991..037836ba7bb 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h @@ -33,7 +33,7 @@ public: ~RegisterContextLLDB () { } virtual void - Invalidate (); + InvalidateAllRegisters (); virtual size_t GetRegisterCount (); diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp index ec915cc0e4e..68a207c9ec9 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp @@ -46,7 +46,7 @@ RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain() } void -RegisterContextMacOSXFrameBackchain::Invalidate () +RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters () { m_cursor_is_valid = false; } diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h b/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h index 9da4e92db21..7997a23a194 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h @@ -36,7 +36,7 @@ public: // Subclasses must override these functions //------------------------------------------------------------------ virtual void - Invalidate (); + InvalidateAllRegisters (); virtual size_t GetRegisterCount (); diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp index 75f92bbef28..30c867e26c6 100644 --- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp @@ -35,6 +35,7 @@ UnwindLLDB::GetFrameCount() { //#define DEBUG_FRAME_SPEED 1 #if DEBUG_FRAME_SPEED +#define FRAME_COUNT 10000 TimeValue time_value (TimeValue::Now()); #endif if (!AddFirstFrame ()) @@ -42,11 +43,15 @@ UnwindLLDB::GetFrameCount() while (AddOneMoreFrame ()) { #if DEBUG_FRAME_SPEED - if ((m_frames.size() % 10000) == 0) + if ((m_frames.size() % FRAME_COUNT) == 0) { TimeValue now(TimeValue::Now()); uint64_t delta_t = now - time_value; - printf ("10000 frames in %llu.%09llu ms\n", delta_t / NSEC_PER_SEC, delta_t % NSEC_PER_SEC); + printf ("%u frames in %llu.%09llu ms (%g frames/sec)\n", + FRAME_COUNT, + delta_t / NSEC_PER_SEC, + delta_t % NSEC_PER_SEC, + (float)FRAME_COUNT / ((float)delta_t / (float)NSEC_PER_SEC)); time_value = now; } #endif diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index 978daa7e9ca..eaf91eb98b1 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -39,7 +39,6 @@ GDBRemoteRegisterContext::GDBRemoteRegisterContext RegisterContext (thread, concrete_frame_idx), m_reg_info (reg_info), m_reg_valid (), - m_reg_valid_stop_id (), m_reg_data (), m_read_all_at_once (read_all_at_once) { @@ -74,7 +73,7 @@ GDBRemoteRegisterContext::GetGDBThread() } void -GDBRemoteRegisterContext::Invalidate () +GDBRemoteRegisterContext::InvalidateAllRegisters () { SetAllRegisterValid (false); } @@ -179,25 +178,41 @@ GDBRemoteRegisterContext::ReadRegisterValue (uint32_t reg, Scalar &value) return false; } +void +GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response) +{ + const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); + assert (reg_info); + + // Invalidate if needed + InvalidateIfNeeded(false); + + const uint32_t reg_byte_size = reg_info->byte_size; + const size_t bytes_copied = response.GetHexBytes (const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)), reg_byte_size, '\xcc'); + bool success = bytes_copied == reg_byte_size; + if (success) + { + m_reg_valid[reg] = true; + } + else if (bytes_copied > 0) + { + // Only set register is valid to false if we copied some bytes, else + // leave it as it was. + m_reg_valid[reg] = false; + } +} + bool GDBRemoteRegisterContext::ReadRegisterBytes (uint32_t reg, DataExtractor &data) { GDBRemoteCommunication &gdb_comm = GetGDBProcess().GetGDBRemote(); -// FIXME: This check isn't right because IsRunning checks the Public state, but this -// is work you need to do - for instance in ShouldStop & friends - before the public -// state has been changed. -// if (gdb_comm.IsRunning()) -// return false; - if (m_reg_valid_stop_id != m_thread.GetProcess().GetStopID()) - { - Invalidate(); - m_reg_valid_stop_id = m_thread.GetProcess().GetStopID(); - } + InvalidateIfNeeded(false); + const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); assert (reg_info); - if (m_reg_valid[reg] == false) + if (!m_reg_valid[reg]) { Mutex::Locker locker; if (gdb_comm.GetSequenceMutex (locker)) @@ -225,28 +240,27 @@ GDBRemoteRegisterContext::ReadRegisterBytes (uint32_t reg, DataExtractor &data) packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg); assert (packet_len < (sizeof(packet) - 1)); if (gdb_comm.SendPacketAndWaitForResponse(packet, response, 1, false)) - if (response.GetHexBytes (const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size)), reg_info->byte_size, '\xcc') == reg_info->byte_size) - m_reg_valid[reg] = true; + PrivateSetRegisterValue (reg, response); } } } + + // Make sure we got a valid register value after reading it + if (!m_reg_valid[reg]) + return false; } - bool reg_is_valid = m_reg_valid[reg]; - if (reg_is_valid) + if (&data != &m_reg_data) { - if (&data != &m_reg_data) - { - // If we aren't extracting into our own buffer (which - // only happens when this function is called from - // ReadRegisterValue(uint32_t, Scalar&)) then - // we transfer bytes from our buffer into the data - // buffer that was passed in - data.SetByteOrder (m_reg_data.GetByteOrder()); - data.SetData (m_reg_data, reg_info->byte_offset, reg_info->byte_size); - } + // If we aren't extracting into our own buffer (which + // only happens when this function is called from + // ReadRegisterValue(uint32_t, Scalar&)) then + // we transfer bytes from our buffer into the data + // buffer that was passed in + data.SetByteOrder (m_reg_data.GetByteOrder()); + data.SetData (m_reg_data, reg_info->byte_offset, reg_info->byte_size); } - return reg_is_valid; + return true; } @@ -323,8 +337,8 @@ GDBRemoteRegisterContext::WriteRegisterBytes (uint32_t reg, DataExtractor &data, eByteOrderHost); // Invalidate all register values - Invalidate (); - + InvalidateIfNeeded (true); + if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), packet.GetString().size(), response, diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h index e20da52527b..72c640ff7a8 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h @@ -25,6 +25,7 @@ class ThreadGDBRemote; class ProcessGDBRemote; +class StringExtractor; class GDBRemoteDynamicRegisterInfo { @@ -189,7 +190,7 @@ public: // Subclasses must override these functions //------------------------------------------------------------------ virtual void - Invalidate (); + InvalidateAllRegisters (); virtual size_t GetRegisterCount (); @@ -225,8 +226,12 @@ public: ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num); protected: + friend class ThreadGDBRemote; void + PrivateSetRegisterValue (uint32_t reg, StringExtractor &response); + + void SetAllRegisterValid (bool b); ProcessGDBRemote & @@ -237,7 +242,6 @@ protected: GDBRemoteDynamicRegisterInfo &m_reg_info; std::vector<bool> m_reg_valid; - uint32_t m_reg_valid_stop_id; lldb_private::DataExtractor m_reg_data; bool m_read_all_at_once; diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 3775d5b9ff6..cee3e6fd8b9 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -975,9 +975,7 @@ ProcessGDBRemote::UpdateThreadListIfNeeded () if (tid != LLDB_INVALID_THREAD_ID) { ThreadSP thread_sp (GetThreadList().FindThreadByID (tid, false)); - if (thread_sp) - thread_sp->GetRegisterContext()->Invalidate(); - else + if (!thread_sp) thread_sp.reset (new ThreadGDBRemote (*this, tid)); curr_thread_list.AddThread(thread_sp); } @@ -1014,6 +1012,8 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) uint32_t tid = LLDB_INVALID_THREAD_ID; addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS; uint32_t exc_data_count = 0; + ThreadSP thread_sp; + while (stop_packet.GetNameColonValue(name, value)) { if (name.compare("metype") == 0) @@ -1035,6 +1035,7 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) { // thread in big endian hex tid = Args::StringToUInt32 (value.c_str(), 0, 16); + thread_sp = m_thread_list.FindThreadByID(tid, false); } else if (name.compare("hexname") == 0) { @@ -1053,8 +1054,25 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) { thread_dispatch_qaddr = Args::StringToUInt64 (value.c_str(), 0, 16); } + else if (name.size() == 2 && ::isxdigit(name[0]) && ::isxdigit(name[1])) + { + // We have a register number that contains an expedited + // register value. Lets supply this register to our thread + // so it won't have to go and read it. + if (thread_sp) + { + uint32_t reg = Args::StringToUInt32 (name.c_str(), UINT32_MAX, 16); + + if (reg != UINT32_MAX) + { + StringExtractor reg_value_extractor; + // Swap "value" over into "reg_value_extractor" + reg_value_extractor.GetStringRef().swap(value); + static_cast<ThreadGDBRemote *> (thread_sp.get())->PrivateSetRegisterValue (reg, reg_value_extractor); + } + } + } } - ThreadSP thread_sp (m_thread_list.FindThreadByID(tid, false)); if (thread_sp) { diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index 091feb9e649..b8108bfd383 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -37,7 +37,8 @@ ThreadGDBRemote::ThreadGDBRemote (ProcessGDBRemote &process, lldb::tid_t tid) : Thread(process, tid), m_thread_name (), m_dispatch_queue_name (), - m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS) + m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS), + m_thread_stop_reason_stop_id (0) { // ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD | GDBR_LOG_VERBOSE, "ThreadGDBRemote::ThreadGDBRemote ( pid = %i, tid = 0x%4.4x, )", m_process.GetID(), GetID()); ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID()); @@ -116,14 +117,18 @@ ThreadGDBRemote::WillResume (StateType resume_state) void ThreadGDBRemote::RefreshStateAfterStop() { - // Invalidate all registers in our register context - GetRegisterContext()->Invalidate(); + // Invalidate all registers in our register context. We don't set "force" to + // true because the stop reply packet might have had some register values + // that were expedited and these will already be copied into the register + // context by the time this function gets called. The GDBRemoteRegisterContext + // class has been made smart enough to detect when it needs to invalidate + // which registers are valid by putting hooks in the register read and + // register supply functions where they check the process stop ID and do + // the right thing. + const bool force = false; + GetRegisterContext()->InvalidateIfNeeded (force); } -// Whether to use the new native unwinder (UnwindLLDB) or the libunwind-remote based unwinder for -// stack walks on i386/x86_64 -#define USE_NATIVE_UNWINDER - Unwind * ThreadGDBRemote::GetUnwinder () { @@ -132,11 +137,7 @@ ThreadGDBRemote::GetUnwinder () const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ()); if (target_arch == ArchSpec("x86_64") || target_arch == ArchSpec("i386")) { -#if defined (USE_NATIVE_UNWINDER) m_unwinder_ap.reset (new UnwindLLDB (*this)); -#else - m_unwinder_ap.reset (new UnwindLibUnwind (*this, GetGDBProcess().GetLibUnwindAddressSpace())); -#endif } else { @@ -198,6 +199,14 @@ ThreadGDBRemote::CreateRegisterContextForFrame (StackFrame *frame) return reg_ctx_sp; } +void +ThreadGDBRemote::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response) +{ + GDBRemoteRegisterContext *gdb_reg_ctx = static_cast<GDBRemoteRegisterContext *>(GetRegisterContext ().get()); + assert (gdb_reg_ctx); + gdb_reg_ctx->PrivateSetRegisterValue (reg, response); +} + bool ThreadGDBRemote::SaveFrameZeroState (RegisterCheckpoint &checkpoint) { @@ -217,7 +226,7 @@ ThreadGDBRemote::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint) if (frame_sp) { bool ret = frame_sp->GetRegisterContext()->WriteAllRegisterValues (checkpoint.GetData()); - frame_sp->GetRegisterContext()->Invalidate(); + frame_sp->GetRegisterContext()->InvalidateIfNeeded(true); ClearStackFrames(); return ret; } @@ -227,8 +236,19 @@ ThreadGDBRemote::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint) lldb::StopInfoSP ThreadGDBRemote::GetPrivateStopReason () { - if (m_actual_stop_info_sp.get() == NULL || m_actual_stop_info_sp->IsValid() == false) + const uint32_t process_stop_id = GetProcess().GetStopID(); + if (m_thread_stop_reason_stop_id != process_stop_id || + (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid())) { + // If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason + // for this thread, then m_actual_stop_info_sp will not ever contain + // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false" + // check will never be able to tell us if we have the correct stop info + // for this thread and we will continually send qThreadStopInfo packets + // down to the remote GDB server, so we need to keep our own notion + // of the stop ID that m_actual_stop_info_sp is valid for (even if it + // contains nothing). We use m_thread_stop_reason_stop_id for this below. + m_thread_stop_reason_stop_id = process_stop_id; m_actual_stop_info_sp.reset(); char packet[256]; @@ -236,7 +256,6 @@ ThreadGDBRemote::GetPrivateStopReason () StringExtractorGDBRemote stop_packet; if (GetGDBProcess().GetGDBRemote().SendPacketAndWaitForResponse(packet, stop_packet, 1, false)) { - std::string copy(stop_packet.GetStringRef()); GetGDBProcess().SetThreadStopInfo (stop_packet); } } diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h index 37aae88ed34..3bf54afa9be 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h @@ -108,12 +108,20 @@ public: } protected: + + friend class ProcessGDBRemote; + + void + PrivateSetRegisterValue (uint32_t reg, + StringExtractor &response); + //------------------------------------------------------------------ // Member variables. //------------------------------------------------------------------ std::string m_thread_name; std::string m_dispatch_queue_name; lldb::addr_t m_thread_dispatch_qaddr; + uint32_t m_thread_stop_reason_stop_id; //------------------------------------------------------------------ // Member variables. //------------------------------------------------------------------ diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index bc105ccf754..36f21ac56a5 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -234,7 +234,7 @@ Process::Process(Target &target, Listener &listener) : m_addr_byte_size (0), m_abi_sp (), m_process_input_reader (), - m_stdio_communication ("lldb.process.stdio"), + m_stdio_communication ("process.stdio"), m_stdio_communication_mutex (Mutex::eMutexTypeRecursive), m_stdout_data (), m_memory_cache () @@ -2004,7 +2004,9 @@ Process::StartPrivateStateThread () // Create a thread that watches our internal state and controls which // events make it to clients (into the DCProcess event queue). - m_private_state_thread = Host::ThreadCreate ("<lldb.process.internal-state>", Process::PrivateStateThread, this, NULL); + char thread_name[1024]; + snprintf(thread_name, sizeof(thread_name), "<lldb.process.internal-state(pid=%i)>", GetID()); + m_private_state_thread = Host::ThreadCreate (thread_name, Process::PrivateStateThread, this, NULL); return m_private_state_thread != LLDB_INVALID_HOST_THREAD; } diff --git a/lldb/source/Target/RegisterContext.cpp b/lldb/source/Target/RegisterContext.cpp index 1edaf4964d8..814e5369d23 100644 --- a/lldb/source/Target/RegisterContext.cpp +++ b/lldb/source/Target/RegisterContext.cpp @@ -16,6 +16,7 @@ #include "lldb/Core/Scalar.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/StackFrame.h" +#include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" using namespace lldb; @@ -23,7 +24,8 @@ using namespace lldb_private; RegisterContext::RegisterContext (Thread &thread, uint32_t concrete_frame_idx) : m_thread (thread), - m_concrete_frame_idx (concrete_frame_idx) + m_concrete_frame_idx (concrete_frame_idx), + m_stop_id (thread.GetProcess().GetStopID()) { } @@ -34,6 +36,19 @@ RegisterContext::~RegisterContext() { } +void +RegisterContext::InvalidateIfNeeded (bool force) +{ + const uint32_t this_stop_id = GetStopID(); + const uint32_t process_stop_id = m_thread.GetProcess().GetStopID(); + if (force || process_stop_id != this_stop_id) + { + InvalidateAllRegisters (); + SetStopID (process_stop_id); + } +} + + const RegisterInfo * RegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx) { diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 6f5858a8acc..f89f5e4de8f 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -961,7 +961,11 @@ Target::EvaluateExpression { // Make sure we aren't just trying to see the value of a persistent // variable (something like "$0") - lldb::ClangExpressionVariableSP persistent_var_sp (m_persistent_variables.GetVariable (expr_cstr)); + lldb::ClangExpressionVariableSP persistent_var_sp; + // Only check for persistent variables the expression starts with a '$' + if (expr_cstr[0] == '$') + persistent_var_sp = m_persistent_variables.GetVariable (expr_cstr); + if (persistent_var_sp) { result_valobj_sp = persistent_var_sp->GetValueObject (); |

