Fixed SBTarget attach calls to properly deal with being connected to a remotely

connected process connection.

Also added support for more kinds of continue packet when multiple threads
need to continue where some want to continue with signals.

llvm-svn: 133785
This commit is contained in:
Greg Clayton 2011-06-24 03:21:43 +00:00
parent 1da39282ec
commit 0c74e78d63
3 changed files with 110 additions and 50 deletions

View File

@ -479,15 +479,15 @@ SBProcess::GetAddressByteSize () const
SBError
SBProcess::Continue ()
{
Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
log->Printf ("SBProcess(%p)::Continue ()...", m_opaque_sp.get());
SBError sb_error;
if (IsValid())
if (m_opaque_sp)
{
Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
Error error (m_opaque_sp->Resume());
if (error.Success())
{
@ -545,7 +545,7 @@ SBError
SBProcess::Stop ()
{
SBError sb_error;
if (IsValid())
if (m_opaque_sp)
{
Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
sb_error.SetError (m_opaque_sp->Halt());

View File

@ -282,11 +282,43 @@ SBTarget::AttachToProcessWithID
if (m_opaque_sp)
{
Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
if (listener.IsValid())
sb_process.SetProcess (m_opaque_sp->CreateProcess (listener.ref()));
StateType state = eStateInvalid;
sb_process.SetProcess (m_opaque_sp->GetProcessSP());
if (sb_process.IsValid())
{
state = sb_process->GetState();
if (sb_process->IsAlive() && state != eStateConnected)
{
if (state == eStateAttaching)
error.SetErrorString ("process attach is in progress");
else
error.SetErrorString ("a process is already being debugged");
sb_process.Clear();
return sb_process;
}
}
if (state == eStateConnected)
{
// If we are already connected, then we have already specified the
// listener, so if a valid listener is supplied, we need to error out
// to let the client know.
if (listener.IsValid())
{
error.SetErrorString ("process is connected and already has a listener, pass empty listener");
sb_process.Clear();
return sb_process;
}
}
else
sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
{
if (listener.IsValid())
sb_process.SetProcess (m_opaque_sp->CreateProcess (listener.ref()));
else
sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
}
if (sb_process.IsValid())
{
@ -323,10 +355,42 @@ SBTarget::AttachToProcessWithName
{
Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
if (listener.IsValid())
sb_process.SetProcess (m_opaque_sp->CreateProcess (listener.ref()));
StateType state = eStateInvalid;
sb_process.SetProcess (m_opaque_sp->GetProcessSP());
if (sb_process.IsValid())
{
state = sb_process->GetState();
if (sb_process->IsAlive() && state != eStateConnected)
{
if (state == eStateAttaching)
error.SetErrorString ("process attach is in progress");
else
error.SetErrorString ("a process is already being debugged");
sb_process.Clear();
return sb_process;
}
}
if (state == eStateConnected)
{
// If we are already connected, then we have already specified the
// listener, so if a valid listener is supplied, we need to error out
// to let the client know.
if (listener.IsValid())
{
error.SetErrorString ("process is connected and already has a listener, pass empty listener");
sb_process.Clear();
return sb_process;
}
}
else
sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
{
if (listener.IsValid())
sb_process.SetProcess (m_opaque_sp->CreateProcess (listener.ref()));
else
sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
}
if (sb_process.IsValid())
{

View File

@ -901,7 +901,6 @@ ProcessGDBRemote::DoResume ()
if (continue_packet_error)
{
continue_packet_error = false;
// Either no vCont support, or we tried to use part of the vCont
// packet that wasn't supported by the remote GDB server.
// We need to try and make a simple packet that can do our continue
@ -916,7 +915,8 @@ ProcessGDBRemote::DoResume ()
{
// All threads are resuming...
m_gdb_comm.SetCurrentThreadForRun (-1);
continue_packet.PutChar ('c');
continue_packet.PutChar ('c');
continue_packet_error = false;
}
else if (num_continue_c_tids == 1 &&
num_continue_C_tids == 0 &&
@ -926,57 +926,60 @@ ProcessGDBRemote::DoResume ()
// Only one thread is continuing
m_gdb_comm.SetCurrentThreadForRun (m_continue_c_tids.front());
continue_packet.PutChar ('c');
}
else
{
// We can't represent this continue packet....
continue_packet_error = true;
continue_packet_error = false;
}
}
if (!continue_packet_error && num_continue_C_tids > 0)
if (continue_packet_error && num_continue_C_tids > 0)
{
if (num_continue_C_tids == num_threads)
if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&
num_continue_C_tids > 0 &&
num_continue_s_tids == 0 &&
num_continue_S_tids == 0 )
{
const int continue_signo = m_continue_C_tids.front().second;
// Only one thread is continuing
if (num_continue_C_tids > 1)
{
for (size_t i=1; i<num_threads; ++i)
// More that one thread with a signal, yet we don't have
// vCont support and we are being asked to resume each
// thread with a signal, we need to make sure they are
// all the same signal, or we can't issue the continue
// accurately with the current support...
if (num_continue_C_tids > 1)
{
if (m_continue_C_tids[i].second != continue_signo)
continue_packet_error = true;
continue_packet_error = false;
for (size_t i=1; i<m_continue_C_tids.size(); ++i)
{
if (m_continue_C_tids[i].second != continue_signo)
continue_packet_error = true;
}
}
if (!continue_packet_error)
m_gdb_comm.SetCurrentThreadForRun (-1);
}
else
{
// Set the continue thread ID
continue_packet_error = false;
m_gdb_comm.SetCurrentThreadForRun (m_continue_C_tids.front().first);
}
if (!continue_packet_error)
{
// Add threads continuing with the same signo...
m_gdb_comm.SetCurrentThreadForRun (-1);
continue_packet.Printf("C%2.2x", continue_signo);
}
}
else if (num_continue_c_tids == 0 &&
num_continue_C_tids == 1 &&
num_continue_s_tids == 0 &&
num_continue_S_tids == 0 )
{
// Only one thread is continuing with signal
m_gdb_comm.SetCurrentThreadForRun (m_continue_C_tids.front().first);
continue_packet.Printf("C%2.2x", m_continue_C_tids.front().second);
}
else
{
// We can't represent this continue packet....
continue_packet_error = true;
}
}
if (!continue_packet_error && num_continue_s_tids > 0)
if (continue_packet_error && num_continue_s_tids > 0)
{
if (num_continue_s_tids == num_threads)
{
// All threads are resuming...
m_gdb_comm.SetCurrentThreadForRun (-1);
continue_packet.PutChar ('s');
continue_packet.PutChar ('s');
continue_packet_error = false;
}
else if (num_continue_c_tids == 0 &&
num_continue_C_tids == 0 &&
@ -986,11 +989,7 @@ ProcessGDBRemote::DoResume ()
// Only one thread is stepping
m_gdb_comm.SetCurrentThreadForRun (m_continue_s_tids.front());
continue_packet.PutChar ('s');
}
else
{
// We can't represent this continue packet....
continue_packet_error = true;
continue_packet_error = false;
}
}
@ -1000,6 +999,7 @@ ProcessGDBRemote::DoResume ()
{
const int step_signo = m_continue_S_tids.front().second;
// Are all threads trying to step with the same signal?
continue_packet_error = false;
if (num_continue_S_tids > 1)
{
for (size_t i=1; i<num_threads; ++i)
@ -1023,11 +1023,7 @@ ProcessGDBRemote::DoResume ()
// Only one thread is stepping with signal
m_gdb_comm.SetCurrentThreadForRun (m_continue_S_tids.front().first);
continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second);
}
else
{
// We can't represent this continue packet....
continue_packet_error = true;
continue_packet_error = false;
}
}
}