Sped up the shutdown time on MacOSX by quite a bit by making sure any

threads that we spawn let us know when they are going away and that we
don't timeout waiting for a message from threads that have gone away.
We also now don't expect the "k" packet (kill) to send a response. This
greatly speeds up debugger shutdown performance. The test suite now runs
quite a bit faster.

Added a fix to the variable display code that fixes the display of
base classes. We were assuming the virtual or normal base class offsets
were being given in bit sizes, but they were being given as character
sizes, so we needed to multiply the offset by 8. This wasn't affecting
the expression parser, but it was affecting the correct display of C++
class base classes and all of their children.

llvm-svn: 124024
This commit is contained in:
Greg Clayton 2011-01-22 07:12:45 +00:00
parent 9c399a29fd
commit 6ed95945ed
7 changed files with 60 additions and 61 deletions

View File

@ -87,14 +87,23 @@ GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_
}
size_t
GDBRemoteCommunication::SendAck (char ack_char)
GDBRemoteCommunication::SendAck ()
{
Mutex::Locker locker(m_sequence_mutex);
ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: %c", ack_char);
ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: +");
ConnectionStatus status = eConnectionStatusSuccess;
char ack_char = '+';
return Write (&ack_char, 1, status, NULL) == 1;
}
size_t
GDBRemoteCommunication::SendNack ()
{
ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: -");
ConnectionStatus status = eConnectionStatusSuccess;
char nack_char = '-';
return Write (&nack_char, 1, status, NULL) == 1;
}
size_t
GDBRemoteCommunication::SendPacketAndWaitForResponse
(
@ -141,7 +150,8 @@ GDBRemoteCommunication::SendPacketAndWaitForResponse
m_async_packet_predicate.SetValue (true, eBroadcastNever);
bool timed_out = false;
if (SendInterrupt(locker, 1, &timed_out))
bool sent_interrupt = false;
if (SendInterrupt(locker, 1, sent_interrupt, timed_out))
{
if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
{
@ -443,8 +453,9 @@ GDBRemoteCommunication::SendAsyncSignal (int signo)
{
m_async_signal = signo;
bool timed_out = false;
bool sent_interrupt = false;
Mutex::Locker locker;
if (SendInterrupt (locker, 1, &timed_out))
if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
return true;
m_async_signal = -1;
return false;
@ -461,10 +472,16 @@ GDBRemoteCommunication::SendAsyncSignal (int signo)
// (gdb remote protocol requires this), and do what we need to do, then resume.
bool
GDBRemoteCommunication::SendInterrupt (Mutex::Locker& locker, uint32_t seconds_to_wait_for_stop, bool *timed_out)
GDBRemoteCommunication::SendInterrupt
(
Mutex::Locker& locker,
uint32_t seconds_to_wait_for_stop,
bool &sent_interrupt,
bool &timed_out
)
{
if (timed_out)
*timed_out = false;
sent_interrupt = false;
timed_out = false;
if (IsConnected() && IsRunning())
{
@ -484,8 +501,9 @@ GDBRemoteCommunication::SendInterrupt (Mutex::Locker& locker, uint32_t seconds_t
ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: \\x03");
if (Write (&ctrl_c, 1, status, NULL) > 0)
{
sent_interrupt = true;
if (seconds_to_wait_for_stop)
m_private_is_running.WaitForValueEqualTo (false, &timeout, timed_out);
m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out);
return true;
}
}
@ -553,9 +571,9 @@ GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response,
checksum_error = packet_checksum != actual_checksum;
// Send the ack or nack if needed
if (checksum_error || !success)
SendAck('-');
SendNack();
else
SendAck('+');
SendAck();
}
}
else

View File

@ -87,7 +87,11 @@ public:
GetAck (uint32_t timeout_seconds);
size_t
SendAck (char ack_char);
SendAck ();
size_t
SendNack ();
char
CalculcateChecksum (const char *payload,
@ -117,7 +121,8 @@ public:
bool
SendInterrupt (lldb_private::Mutex::Locker &locker,
uint32_t seconds_to_wait_for_stop,
bool *timed_out = NULL);
bool &sent_interrupt,
bool &timed_out);
bool
GetSequenceMutex(lldb_private::Mutex::Locker& locker);

View File

@ -541,7 +541,7 @@ ProcessGDBRemote::ConnectToDebugserver (const char *host_port)
if (m_gdb_comm.StartReadThread(&error))
{
// Send an initial ack
m_gdb_comm.SendAck('+');
m_gdb_comm.SendAck();
if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
m_debugserver_thread = Host::StartMonitoringChildProcess (MonitorDebugserverProcess,
@ -1142,24 +1142,16 @@ ProcessGDBRemote::DoHalt (bool &caused_stop)
{
Error error;
if (m_gdb_comm.IsRunning())
{
caused_stop = true;
bool timed_out = false;
Mutex::Locker locker;
if (!m_gdb_comm.SendInterrupt (locker, 2, &timed_out))
if (!m_gdb_comm.SendInterrupt (locker, 2, caused_stop, timed_out))
{
if (timed_out)
error.SetErrorString("timed out sending interrupt packet");
else
error.SetErrorString("unknown error sending interrupt packet");
}
}
else
{
caused_stop = false;
}
return error;
}
@ -1172,11 +1164,12 @@ ProcessGDBRemote::WillDetach ()
if (m_gdb_comm.IsRunning())
{
bool timed_out = false;
bool sent_interrupt = false;
Mutex::Locker locker;
PausePrivateStateThread();
m_thread_list.DiscardThreadPlans();
m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
if (!m_gdb_comm.SendInterrupt (locker, 2, &timed_out))
if (!m_gdb_comm.SendInterrupt (locker, 2, sent_interrupt, timed_out))
{
if (timed_out)
error.SetErrorString("timed out sending interrupt packet");
@ -1238,22 +1231,10 @@ ProcessGDBRemote::DoDestroy ()
log->Printf ("ProcessGDBRemote::DoDestroy()");
// Interrupt if our inferior is running...
Mutex::Locker locker;
m_gdb_comm.SendInterrupt (locker, 1);
DisableAllBreakpointSites ();
SetExitStatus(-1, "process killed");
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse("k", response, 1, false))
if (m_gdb_comm.IsConnected())
{
log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
if (log)
{
if (response.IsOKPacket())
log->Printf ("ProcessGDBRemote::DoDestroy() kill was successful");
else
log->Printf ("ProcessGDBRemote::DoDestroy() kill failed: %s", response.GetStringRef().c_str());
}
// Don't get a response when killing our
m_gdb_comm.SendPacket ("k", 1);
}
StopAsyncThread ();

View File

@ -2475,9 +2475,9 @@ ClangASTContext::GetChildClangTypeAtIndex
if (base_class->isVirtual())
bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity();
bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
else
bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity();
bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
// Base classes should be a multiple of 8 bits in size
assert (bit_offset % 8 == 0);

View File

@ -392,9 +392,9 @@ ClangASTType::DumpValue
continue;
if (base_class->isVirtual())
field_bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity();
field_bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
else
field_bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity();
field_bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
field_byte_offset = field_bit_offset / 8;
assert (field_bit_offset % 8 == 0);
if (child_idx == 0)

View File

@ -407,7 +407,6 @@ Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp)
event_sp))
state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
if (log)
log->Printf ("Process::%s (timeout = %p, event_sp) => %s",
__FUNCTION__,
@ -427,7 +426,6 @@ Process::PeekAtStateChangedEvents ()
Event *event_ptr;
event_ptr = m_listener.PeekAtNextEventForBroadcasterWithType (this,
eBroadcastBitStateChanged);
log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
if (log)
{
if (event_ptr)
@ -463,7 +461,6 @@ Process::WaitForStateChangedEventsPrivate (const TimeValue *timeout, EventSP &ev
// This is a bit of a hack, but when we wait here we could very well return
// to the command-line, and that could disable the log, which would render the
// log we got above invalid.
log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
if (log)
log->Printf ("Process::%s (timeout = %p, event_sp) => %s", __FUNCTION__, timeout, StateAsCString(state));
return state;
@ -2140,7 +2137,6 @@ Process::RunPrivateStateThread ()
break;
}
log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
if (log)
log->Printf ("Process::%s (arg = %p, pid = %i) got a control event: %d", __FUNCTION__, this, GetID(), event_sp->GetType());
@ -2160,7 +2156,6 @@ Process::RunPrivateStateThread ()
internal_state == eStateExited ||
internal_state == eStateDetached )
{
log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
if (log)
log->Printf ("Process::%s (arg = %p, pid = %i) about to exit with internal state %s...", __FUNCTION__, this, GetID(), StateAsCString(internal_state));
@ -2169,10 +2164,11 @@ Process::RunPrivateStateThread ()
}
// Verify log is still enabled before attempting to write to it...
log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
if (log)
log->Printf ("Process::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, this, GetID());
m_private_state_control_wait.SetValue (true, eBroadcastAlways);
m_private_state_thread = LLDB_INVALID_HOST_THREAD;
return NULL;
}

View File

@ -3123,11 +3123,10 @@ RNBRemote::HandlePacket_D (const char *p)
rnb_err_t
RNBRemote::HandlePacket_k (const char *p)
{
if (!m_ctx.HasValidProcessID())
return SendPacket ("E26");
if (!DNBProcessKill (m_ctx.ProcessID()))
return SendPacket ("E27");
return SendPacket ("OK");
// No response to should be sent to the kill packet
if (m_ctx.HasValidProcessID())
DNBProcessKill (m_ctx.ProcessID());
return rnb_success;
}
rnb_err_t