forked from OSchip/llvm-project
Patch from Matt Kopec <matt.kopec@intel.com> to fix the problem that if two breakpoints were set on consecutive addresses, the continue from the
first breakpoint would skip the second. llvm-svn: 166000
This commit is contained in:
parent
244beb42ce
commit
5d88a068ee
lldb
include/lldb/Target
source
Core
Plugins/Process
MacOSX-Kernel
Utility
gdb-remote
mach-core
Target
test/lang/cpp/dynamic-value
|
@ -858,6 +858,10 @@ protected:
|
|||
virtual lldb_private::Unwind *
|
||||
GetUnwinder ();
|
||||
|
||||
// Check to see whether the thread is still at the last breakpoint hit that stopped it.
|
||||
virtual const bool
|
||||
IsStillAtLastBreakpointHit();
|
||||
|
||||
lldb::StackFrameListSP
|
||||
GetStackFrameList ();
|
||||
|
||||
|
|
|
@ -1952,7 +1952,7 @@ Debugger::FormatPrompt
|
|||
else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0)
|
||||
{
|
||||
StopInfoSP stop_info_sp = thread->GetStopInfo ();
|
||||
if (stop_info_sp)
|
||||
if (stop_info_sp && stop_info_sp->IsValid())
|
||||
{
|
||||
cstr = stop_info_sp->GetDescription();
|
||||
if (cstr && cstr[0])
|
||||
|
@ -1965,7 +1965,7 @@ Debugger::FormatPrompt
|
|||
else if (::strncmp (var_name_begin, "return-value}", strlen("return-value}")) == 0)
|
||||
{
|
||||
StopInfoSP stop_info_sp = thread->GetStopInfo ();
|
||||
if (stop_info_sp)
|
||||
if (stop_info_sp && stop_info_sp->IsValid())
|
||||
{
|
||||
ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
|
||||
if (return_valobj_sp)
|
||||
|
|
|
@ -179,6 +179,9 @@ ThreadKDP::GetPrivateStopReason ()
|
|||
if (m_thread_stop_reason_stop_id != process_stop_id ||
|
||||
(m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
|
||||
{
|
||||
if (IsStillAtLastBreakpointHit())
|
||||
return m_actual_stop_info_sp;
|
||||
|
||||
if (m_cached_stop_info_sp)
|
||||
SetStopInfo (m_cached_stop_info_sp);
|
||||
else
|
||||
|
|
|
@ -107,6 +107,9 @@ ThreadMemory::GetPrivateStopReason ()
|
|||
if (m_thread_stop_reason_stop_id != process_stop_id ||
|
||||
(m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
|
||||
{
|
||||
if (IsStillAtLastBreakpointHit())
|
||||
return m_actual_stop_info_sp;
|
||||
|
||||
// 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"
|
||||
|
|
|
@ -225,6 +225,9 @@ ThreadGDBRemote::GetPrivateStopReason ()
|
|||
if (m_thread_stop_reason_stop_id != process_stop_id ||
|
||||
(m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
|
||||
{
|
||||
if (IsStillAtLastBreakpointHit())
|
||||
return m_actual_stop_info_sp;
|
||||
|
||||
// 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"
|
||||
|
|
|
@ -136,6 +136,9 @@ ThreadMachCore::GetPrivateStopReason ()
|
|||
if (m_thread_stop_reason_stop_id != process_stop_id ||
|
||||
(m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
|
||||
{
|
||||
if (IsStillAtLastBreakpointHit())
|
||||
return m_actual_stop_info_sp;
|
||||
|
||||
// TODO: can we query the initial state of the thread here?
|
||||
// For now I am just going to pretend that a SIGSTOP happened.
|
||||
|
||||
|
|
|
@ -3741,7 +3741,7 @@ Process::ProcessEventData::DoOnRemoval (Event *event_ptr)
|
|||
}
|
||||
|
||||
StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
|
||||
if (stop_info_sp)
|
||||
if (stop_info_sp && stop_info_sp->IsValid())
|
||||
{
|
||||
stop_info_sp->PerformAction(event_ptr);
|
||||
// The stop action might restart the target. If it does, then we want to mark that in the
|
||||
|
@ -4905,7 +4905,8 @@ Process::GetThreadStatus (Stream &strm,
|
|||
{
|
||||
if (only_threads_with_stop_reason)
|
||||
{
|
||||
if (thread->GetStopInfo().get() == NULL)
|
||||
StopInfoSP stop_info_sp = thread->GetStopInfo();
|
||||
if (stop_info_sp.get() == NULL || !stop_info_sp->IsValid())
|
||||
continue;
|
||||
}
|
||||
thread->GetStatus (strm,
|
||||
|
|
|
@ -440,9 +440,11 @@ Thread::SetupForResume ()
|
|||
// telling the current plan it will resume, since we might change what the current
|
||||
// plan is.
|
||||
|
||||
lldb::addr_t pc = GetRegisterContext()->GetPC();
|
||||
BreakpointSiteSP bp_site_sp = GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
|
||||
if (bp_site_sp && bp_site_sp->IsEnabled())
|
||||
StopReason stop_reason = lldb::eStopReasonInvalid;
|
||||
StopInfoSP stop_info_sp = GetStopInfo();
|
||||
if (stop_info_sp.get())
|
||||
stop_reason = stop_info_sp->GetStopReason();
|
||||
if (stop_reason == lldb::eStopReasonBreakpoint)
|
||||
{
|
||||
// Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything
|
||||
// special to step over a breakpoint.
|
||||
|
@ -506,7 +508,7 @@ Thread::WillResume (StateType resume_state)
|
|||
// If the WillResume for the plan says we are faking a resume, then it will have set an appropriate stop info.
|
||||
// In that case, don't reset it here.
|
||||
|
||||
if (need_to_resume)
|
||||
if (need_to_resume && resume_state != eStateSuspended)
|
||||
{
|
||||
m_actual_stop_info_sp.reset();
|
||||
}
|
||||
|
@ -1713,3 +1715,22 @@ Thread::Flush ()
|
|||
ClearStackFrames ();
|
||||
m_reg_context_sp.reset();
|
||||
}
|
||||
|
||||
const bool
|
||||
Thread::IsStillAtLastBreakpointHit ()
|
||||
{
|
||||
// If we are currently stopped at a breakpoint, always return that stopinfo and don't reset it.
|
||||
// This allows threads to maintain their breakpoint stopinfo, such as when thread-stepping in
|
||||
// multithreaded programs.
|
||||
if (m_actual_stop_info_sp) {
|
||||
StopReason stop_reason = m_actual_stop_info_sp->GetStopReason();
|
||||
if (stop_reason == lldb::eStopReasonBreakpoint) {
|
||||
uint64_t value = m_actual_stop_info_sp->GetValue();
|
||||
lldb::addr_t pc = GetRegisterContext()->GetPC();
|
||||
BreakpointSiteSP bp_site_sp = GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
|
||||
if (bp_site_sp && value == bp_site_sp->GetID())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@ public:
|
|||
doSomething (A &anotherA)
|
||||
{
|
||||
printf ("In A %p doing something with %d.\n", this, m_a_value);
|
||||
printf ("Also have another A at %p: %d.\n", &anotherA, anotherA.Value()); // Break here in doSomething.
|
||||
int tmp_value = anotherA.Value();
|
||||
printf ("Also have another A at %p: %d.\n", &anotherA, tmp_value); // Break here in doSomething.
|
||||
}
|
||||
|
||||
int
|
||||
|
|
Loading…
Reference in New Issue