diff --git a/lldb/include/lldb/API/SBCommunication.h b/lldb/include/lldb/API/SBCommunication.h index 9763015c9c1e..9485f57d61fe 100644 --- a/lldb/include/lldb/API/SBCommunication.h +++ b/lldb/include/lldb/API/SBCommunication.h @@ -40,15 +40,6 @@ public: lldb::ConnectionStatus AdoptFileDesriptor (int fd, bool owns_fd); - lldb::ConnectionStatus - CheckIfBytesAvailable (); - - lldb::ConnectionStatus - WaitForBytesAvailableInfinite (); - - lldb::ConnectionStatus - WaitForBytesAvailableWithTimeout (uint32_t timeout_usec); - lldb::ConnectionStatus Connect (const char *url); diff --git a/lldb/include/lldb/Core/Communication.h b/lldb/include/lldb/Core/Communication.h index 3b47412d0616..c5401459e450 100644 --- a/lldb/include/lldb/Core/Communication.h +++ b/lldb/include/lldb/Core/Communication.h @@ -120,20 +120,6 @@ public: void Clear (); - //------------------------------------------------------------------ - /// Poll for bytes available if the communications supports it. - /// - /// @param[in] timeout_usec - /// A timeout value in micro-seconds, UINT32_MAX for infinite - /// wait. - /// - /// @return - /// \b True if the bytes are, or became available within the - /// timeout period, \b false otherwise. - //------------------------------------------------------------------ - virtual lldb::ConnectionStatus - BytesAvailable (uint32_t timeout_usec, Error *error_ptr); - //------------------------------------------------------------------ /// Connect using the current connection by passing \a url to its /// connect function. @@ -185,10 +171,7 @@ public: /// Read bytes from the current connection. /// /// If no read thread is running, this function call the - /// connection's Connection::BytesAvailable(uint32_t) method to - /// wait for available data, and then call the - /// Connection::Read(void *, size_t) function to get any available - /// bytes if Connection::BytesAvailable(uint32_t) returned true. + /// connection's Connection::Read(...) function to get any available. /// /// If a read thread has been started, this function will check for /// any cached bytes that have already been read and return any @@ -212,7 +195,6 @@ public: /// @return /// The number of bytes actually read. /// - /// @see bool Connection::BytesAvailable (uint32_t); /// @see size_t Connection::Read (void *, size_t); //------------------------------------------------------------------ size_t @@ -365,6 +347,7 @@ protected: size_t ReadFromConnection (void *dst, size_t dst_len, + uint32_t timeout_usec, lldb::ConnectionStatus &status, Error *error_ptr); //------------------------------------------------------------------ diff --git a/lldb/include/lldb/Core/Connection.h b/lldb/include/lldb/Core/Connection.h index ca16930e8d07..dde3c4b1022c 100644 --- a/lldb/include/lldb/Core/Connection.h +++ b/lldb/include/lldb/Core/Connection.h @@ -46,24 +46,6 @@ public: virtual ~Connection (); - //------------------------------------------------------------------ - /// Poll for bytes available if the communications supports it. - /// - /// @param[in] timeout_usec - /// A timeout value in micro-seconds. - /// - /// @param[out] error - /// A reference to an error object that should be given an - /// approriate error value if this method returns false. This - /// value can be NULL if the error value should be ignored. - /// - /// @return - /// \b True if the bytes are, or became available within the - /// timeout period, \b false otherwise. - //------------------------------------------------------------------ - virtual lldb::ConnectionStatus - BytesAvailable (uint32_t timeout_usec, Error *error_ptr) = 0; - //------------------------------------------------------------------ /// Connect using the connect string \a url. /// @@ -137,7 +119,11 @@ public: /// @see size_t Communication::Read (void *, size_t, uint32_t); //------------------------------------------------------------------ virtual size_t - Read (void *dst, size_t dst_len, lldb::ConnectionStatus &status, Error *error_ptr) = 0; + Read (void *dst, + size_t dst_len, + uint32_t timeout_usec, + lldb::ConnectionStatus &status, + Error *error_ptr) = 0; //------------------------------------------------------------------ /// The actual write function that attempts to write to the diff --git a/lldb/include/lldb/Core/ConnectionFileDescriptor.h b/lldb/include/lldb/Core/ConnectionFileDescriptor.h index 84b084d46384..3772ce862ac6 100644 --- a/lldb/include/lldb/Core/ConnectionFileDescriptor.h +++ b/lldb/include/lldb/Core/ConnectionFileDescriptor.h @@ -33,9 +33,6 @@ public: virtual bool IsConnected () const; - virtual lldb::ConnectionStatus - BytesAvailable (uint32_t timeout_usec, Error *error_ptr); - virtual lldb::ConnectionStatus Connect (const char *s, Error *error_ptr); @@ -43,12 +40,23 @@ public: Disconnect (Error *error_ptr); virtual size_t - Read (void *dst, size_t dst_len, lldb::ConnectionStatus &status, Error *error_ptr); + Read (void *dst, + size_t dst_len, + uint32_t timeout_usec, + lldb::ConnectionStatus &status, + Error *error_ptr); virtual size_t - Write (const void *src, size_t src_len, lldb::ConnectionStatus &status, Error *error_ptr); + Write (const void *src, + size_t src_len, + lldb::ConnectionStatus &status, + Error *error_ptr); protected: + + lldb::ConnectionStatus + BytesAvailable (uint32_t timeout_usec, Error *error_ptr); + lldb::ConnectionStatus SocketListen (uint16_t listen_port_num, Error *error_ptr); @@ -67,10 +75,14 @@ protected: int m_fd; // Socket we use to communicate once conn established bool m_is_socket; bool m_should_close_fd; // True if this class should close the file descriptor when it goes away. - + uint32_t m_socket_timeout_usec; + static int SetSocketOption(int fd, int level, int option_name, int option_value); + bool + SetSocketRecieveTimeout (uint32_t timeout_usec); + private: DISALLOW_COPY_AND_ASSIGN (ConnectionFileDescriptor); }; diff --git a/lldb/include/lldb/Core/ConnectionMachPort.h b/lldb/include/lldb/Core/ConnectionMachPort.h index 4339758c5c49..5613e7ee8008 100644 --- a/lldb/include/lldb/Core/ConnectionMachPort.h +++ b/lldb/include/lldb/Core/ConnectionMachPort.h @@ -45,6 +45,7 @@ public: virtual size_t Read (void *dst, size_t dst_len, + uint32_t timeout_usec, lldb::ConnectionStatus &status, lldb_private::Error *error_ptr); diff --git a/lldb/include/lldb/Core/ConnectionSharedMemory.h b/lldb/include/lldb/Core/ConnectionSharedMemory.h index 65b41b1fa217..0f9cdcb8a92d 100644 --- a/lldb/include/lldb/Core/ConnectionSharedMemory.h +++ b/lldb/include/lldb/Core/ConnectionSharedMemory.h @@ -44,7 +44,11 @@ public: Disconnect (Error *error_ptr); virtual size_t - Read (void *dst, size_t dst_len, lldb::ConnectionStatus &status, Error *error_ptr); + Read (void *dst, + size_t dst_len, + uint32_t timeout_usec, + lldb::ConnectionStatus &status, + Error *error_ptr); virtual size_t Write (const void *src, size_t src_len, lldb::ConnectionStatus &status, Error *error_ptr); diff --git a/lldb/source/API/SBCommunication.cpp b/lldb/source/API/SBCommunication.cpp index 9db6c444902c..160640683d1a 100644 --- a/lldb/source/API/SBCommunication.cpp +++ b/lldb/source/API/SBCommunication.cpp @@ -58,30 +58,6 @@ SBCommunication::SetCloseOnEOF (bool b) m_opaque->SetCloseOnEOF (b); } -ConnectionStatus -SBCommunication::CheckIfBytesAvailable () -{ - if (m_opaque) - return m_opaque->BytesAvailable (0, NULL); - return eConnectionStatusNoConnection; -} - -ConnectionStatus -SBCommunication::WaitForBytesAvailableInfinite () -{ - if (m_opaque) - return m_opaque->BytesAvailable (UINT32_MAX, NULL); - return eConnectionStatusNoConnection; -} - -ConnectionStatus -SBCommunication::WaitForBytesAvailableWithTimeout (uint32_t timeout_usec) -{ - if (m_opaque) - return m_opaque->BytesAvailable (timeout_usec, NULL); - return eConnectionStatusNoConnection; -} - ConnectionStatus SBCommunication::Connect (const char *url) { diff --git a/lldb/source/Core/Communication.cpp b/lldb/source/Core/Communication.cpp index a603d6c7b78d..3f10d8b63a9e 100644 --- a/lldb/source/Core/Communication.cpp +++ b/lldb/source/Core/Communication.cpp @@ -68,19 +68,6 @@ Communication::Clear() Disconnect (NULL); } -ConnectionStatus -Communication::BytesAvailable (uint32_t timeout_usec, Error *error_ptr) -{ - lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::BytesAvailable (timeout_usec = %u)", this, timeout_usec); - - lldb::ConnectionSP connection_sp (m_connection_sp); - if (connection_sp.get()) - return connection_sp->BytesAvailable (timeout_usec, error_ptr); - if (error_ptr) - error_ptr->SetErrorString("Invalid connection."); - return eConnectionStatusNoConnection; -} - ConnectionStatus Communication::Connect (const char *url, Error *error_ptr) { @@ -139,7 +126,7 @@ size_t Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, ConnectionStatus &status, Error *error_ptr) { lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, - "%p Communication::Read (dst = %p, dst_len = %zu, timeout_usec = %u) connection = %p", + "%p Communication::Read (dst = %p, dst_len = %zu, timeout = %u usec) connection = %p", this, dst, dst_len, @@ -196,9 +183,7 @@ Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, Connectio lldb::ConnectionSP connection_sp (m_connection_sp); if (connection_sp.get()) { - status = connection_sp->BytesAvailable (timeout_usec, error_ptr); - if (status == eConnectionStatusSuccess) - return connection_sp->Read (dst, dst_len, status, error_ptr); + return connection_sp->Read (dst, dst_len, timeout_usec, status, error_ptr); } if (error_ptr) @@ -320,11 +305,15 @@ Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broad } size_t -Communication::ReadFromConnection (void *dst, size_t dst_len, ConnectionStatus &status, Error *error_ptr) +Communication::ReadFromConnection (void *dst, + size_t dst_len, + uint32_t timeout_usec, + ConnectionStatus &status, + Error *error_ptr) { lldb::ConnectionSP connection_sp (m_connection_sp); if (connection_sp.get()) - return connection_sp->Read (dst, dst_len, status, error_ptr); + return connection_sp->Read (dst, dst_len, timeout_usec, status, error_ptr); return 0; } @@ -351,20 +340,15 @@ Communication::ReadThread (void *p) bool done = false; while (!done && comm->m_read_thread_enabled) { - status = comm->BytesAvailable (UINT32_MAX, &error); - - if (status == eConnectionStatusSuccess) + size_t bytes_read = comm->ReadFromConnection (buf, sizeof(buf), 5 * USEC_PER_SEC, status, &error); + if (bytes_read > 0) + comm->AppendBytesToCache (buf, bytes_read, true, status); + else if ((bytes_read == 0) + && status == eConnectionStatusEndOfFile) { - size_t bytes_read = comm->ReadFromConnection (buf, sizeof(buf), status, &error); - if (bytes_read > 0) - comm->AppendBytesToCache (buf, bytes_read, true, status); - else if ((bytes_read == 0) - && status == eConnectionStatusEndOfFile) - { - if (comm->GetCloseOnEOF ()) - comm->Disconnect (); - comm->AppendBytesToCache (buf, bytes_read, true, status); - } + if (comm->GetCloseOnEOF ()) + comm->Disconnect (); + comm->AppendBytesToCache (buf, bytes_read, true, status); } switch (status) @@ -384,7 +368,7 @@ Communication::ReadThread (void *p) case eConnectionStatusError: // Check GetError() for details case eConnectionStatusTimedOut: // Request timed out if (log) - error.LogIfError(log.get(), "%p Communication::BytesAvailable () => status = %i", p, status); + error.LogIfError(log.get(), "%p Communication::ReadFromConnection () => status = %i", p, status); break; } } diff --git a/lldb/source/Core/ConnectionFileDescriptor.cpp b/lldb/source/Core/ConnectionFileDescriptor.cpp index 5d21897cb631..2de4dac31dfa 100644 --- a/lldb/source/Core/ConnectionFileDescriptor.cpp +++ b/lldb/source/Core/ConnectionFileDescriptor.cpp @@ -39,7 +39,8 @@ ConnectionFileDescriptor::ConnectionFileDescriptor () : Connection(), m_fd (-1), m_is_socket (false), - m_should_close_fd (false) + m_should_close_fd (false), + m_socket_timeout_usec(0) { lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT, "%p ConnectionFileDescriptor::ConnectionFileDescriptor ()", @@ -50,7 +51,8 @@ ConnectionFileDescriptor::ConnectionFileDescriptor (int fd, bool owns_fd) : Connection(), m_fd (fd), m_is_socket (false), - m_should_close_fd (owns_fd) + m_should_close_fd (owns_fd), + m_socket_timeout_usec(0) { lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT, "%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)", @@ -185,13 +187,33 @@ ConnectionFileDescriptor::Disconnect (Error *error_ptr) } size_t -ConnectionFileDescriptor::Read (void *dst, size_t dst_len, ConnectionStatus &status, Error *error_ptr) +ConnectionFileDescriptor::Read (void *dst, + size_t dst_len, + uint32_t timeout_usec, + ConnectionStatus &status, + Error *error_ptr) { LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); if (log) log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %zu)...", this, m_fd, dst, dst_len); + if (timeout_usec == UINT32_MAX) + { + if (m_is_socket) + SetSocketRecieveTimeout (0); + status = eConnectionStatusSuccess; + } + else + { + if (m_is_socket && SetSocketRecieveTimeout (timeout_usec)) + status = eConnectionStatusSuccess; + else + status = BytesAvailable (timeout_usec, error_ptr); + } + if (status != eConnectionStatusSuccess) + return 0; + Error error; ssize_t bytes_read = ::read (m_fd, dst, dst_len); if (bytes_read == 0) @@ -370,7 +392,7 @@ ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_pt log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION); if (log) - log->Printf("%p ConnectionFileDescriptor::Write() ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p)...", + log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p)...", this, nfds, m_fd, tv_ptr); const int num_set_fds = ::select (nfds, &read_fds, NULL, NULL, tv_ptr); @@ -381,7 +403,7 @@ ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_pt log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION); if (log) - log->Printf("%p ConnectionFileDescriptor::Write() ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p) => %d, error = %s", + log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p) => %d, error = %s", this, nfds, m_fd, tv_ptr, num_set_fds, error.AsCString()); if (error_ptr) @@ -703,4 +725,25 @@ ConnectionFileDescriptor::SetSocketOption(int fd, int level, int option_name, in return ::setsockopt(fd, level, option_name, option_value_p, sizeof(option_value)); } +bool +ConnectionFileDescriptor::SetSocketRecieveTimeout (uint32_t timeout_usec) +{ + if (m_is_socket) + { + // Check in case timeout for m_fd has already been set to this value + if (timeout_usec == m_socket_timeout_usec) + return true; + + struct timeval timeout; + timeout.tv_sec = timeout_usec / USEC_PER_SEC; + timeout.tv_usec = timeout_usec % USEC_PER_SEC; + if (::setsockopt (m_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == 0) + { + m_socket_timeout_usec = timeout_usec; + return true; + } + } + return false; +} + diff --git a/lldb/source/Core/ConnectionMachPort.cpp b/lldb/source/Core/ConnectionMachPort.cpp index cb0344b60322..ca818d405a20 100644 --- a/lldb/source/Core/ConnectionMachPort.cpp +++ b/lldb/source/Core/ConnectionMachPort.cpp @@ -213,7 +213,11 @@ ConnectionMachPort::Disconnect (Error *error_ptr) } size_t -ConnectionMachPort::Read (void *dst, size_t dst_len, ConnectionStatus &status, Error *error_ptr) +ConnectionMachPort::Read (void *dst, + size_t dst_len, + uint32_t timeout_usec, + ConnectionStatus &status, + Error *error_ptr) { PayloadType payload; diff --git a/lldb/source/Core/ConnectionSharedMemory.cpp b/lldb/source/Core/ConnectionSharedMemory.cpp index 943e0c339a70..625f17a0985b 100644 --- a/lldb/source/Core/ConnectionSharedMemory.cpp +++ b/lldb/source/Core/ConnectionSharedMemory.cpp @@ -80,7 +80,11 @@ ConnectionSharedMemory::Disconnect (Error *error_ptr) } size_t -ConnectionSharedMemory::Read (void *dst, size_t dst_len, ConnectionStatus &status, Error *error_ptr) +ConnectionSharedMemory::Read (void *dst, + size_t dst_len, + uint32_t timeout_usec, + ConnectionStatus &status, + Error *error_ptr) { status = eConnectionStatusSuccess; return 0; diff --git a/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm index 1af1cfe54794..78e08eecdda4 100644 --- a/lldb/source/Host/macosx/Host.mm +++ b/lldb/source/Host/macosx/Host.mm @@ -195,7 +195,7 @@ AcceptPIDFromInferior (void *arg) char pid_str[256]; ::memset (pid_str, 0, sizeof(pid_str)); ConnectionStatus status; - const size_t pid_str_len = file_conn.Read (pid_str, sizeof(pid_str), status, NULL); + const size_t pid_str_len = file_conn.Read (pid_str, sizeof(pid_str), NULL, status, NULL); if (pid_str_len > 0) { int pid = atoi (pid_str); diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index a0ca3af3a27e..517f50100b3f 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -258,26 +258,40 @@ RegisterContextLLDB::InitializeNonZerothFrame() m_current_offset_backed_up_one = -1; addr_t cfa_regval; int row_register_kind = m_full_unwind_plan_sp->GetRegisterKind (); - uint32_t cfa_regnum = m_full_unwind_plan_sp->GetRowForFunctionOffset(0)->GetCFARegister(); - int cfa_offset = m_full_unwind_plan_sp->GetRowForFunctionOffset(0)->GetCFAOffset(); - if (!ReadGPRValue (row_register_kind, cfa_regnum, cfa_regval)) + const UnwindPlan::Row *row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0); + if (row) { - if (log) + uint32_t cfa_regnum = row->GetCFARegister(); + int cfa_offset = row->GetCFAOffset(); + if (!ReadGPRValue (row_register_kind, cfa_regnum, cfa_regval)) { - log->Printf("%*sFrame %u failed to get cfa value", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); + if (log) + { + log->Printf("%*sFrame %u failed to get cfa value", + m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); + } + m_frame_type = eNormalFrame; + return; } - m_frame_type = eNormalFrame; - return; - } - m_cfa = cfa_regval + cfa_offset; + m_cfa = cfa_regval + cfa_offset; - // A couple of sanity checks.. - if (cfa_regval == LLDB_INVALID_ADDRESS || cfa_regval == 0 || cfa_regval == 1) + // A couple of sanity checks.. + if (cfa_regval == LLDB_INVALID_ADDRESS || cfa_regval == 0 || cfa_regval == 1) + { + if (log) + { + log->Printf("%*sFrame %u could not find a valid cfa address", + m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); + } + m_frame_type = eNotAValidFrame; + return; + } + } + else { if (log) { - log->Printf("%*sFrame %u could not find a valid cfa address", + log->Printf("%*sFrame %u could not find a row for function offset zero", m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); } m_frame_type = eNotAValidFrame; diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index c5e11ef33de4..c2c9ddf3bfbb 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -39,16 +39,12 @@ GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, bool is_platform) : Communication(comm_name), m_packet_timeout (60), - m_rx_packet_listener (listener_name), m_sequence_mutex (Mutex::eMutexTypeRecursive), m_public_is_running (false), m_private_is_running (false), m_send_acks (true), m_is_platform (is_platform) { - m_rx_packet_listener.StartListeningForEvents(this, - Communication::eBroadcastBitPacketAvailable | - Communication::eBroadcastBitReadThreadDidExit); } //---------------------------------------------------------------------- @@ -56,12 +52,8 @@ GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, //---------------------------------------------------------------------- GDBRemoteCommunication::~GDBRemoteCommunication() { - m_rx_packet_listener.StopListeningForEvents(this, - Communication::eBroadcastBitPacketAvailable | - Communication::eBroadcastBitReadThreadDidExit); if (IsConnected()) { - StopReadThread(); Disconnect(); } } @@ -167,7 +159,7 @@ char GDBRemoteCommunication::GetAck () { StringExtractorGDBRemote packet; - if (WaitForPacket (packet, m_packet_timeout) == 1) + if (WaitForPacketWithTimeoutMicroSeconds (packet, GetPacketTimeoutInMicroSeconds ()) == 1) return packet.GetChar(); return 0; } @@ -186,99 +178,63 @@ GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr) } size_t -GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &packet, uint32_t timeout_seconds) +GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSeconds (StringExtractorGDBRemote &packet, uint32_t timeout_usec) { Mutex::Locker locker(m_sequence_mutex); - TimeValue timeout_time; - timeout_time = TimeValue::Now(); - timeout_time.OffsetWithSeconds (timeout_seconds); - return WaitForPacketNoLock (packet, &timeout_time); + return WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec); } size_t -GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &packet, const TimeValue* timeout_time_ptr) +GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &packet, uint32_t timeout_usec) { - Mutex::Locker locker(m_sequence_mutex); - return WaitForPacketNoLock (packet, timeout_time_ptr); -} + uint8_t buffer[8192]; + Error error; -size_t -GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &packet, const TimeValue* timeout_time_ptr) -{ - bool checksum_error = false; - packet.Clear (); + // Check for a packet from our cache first without trying any reading... + if (CheckForPacket (NULL, 0, packet)) + return packet.GetStringRef().size(); - EventSP event_sp; - - if (m_rx_packet_listener.WaitForEvent (timeout_time_ptr, event_sp)) + bool timed_out = false; + while (IsConnected() && !timed_out) { - const uint32_t event_type = event_sp->GetType(); - if (event_type | Communication::eBroadcastBitPacketAvailable) + lldb::ConnectionStatus status; + size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error); + if (bytes_read > 0) { - const EventDataBytes *event_bytes = EventDataBytes::GetEventDataFromEvent(event_sp.get()); - if (event_bytes) + if (CheckForPacket (buffer, bytes_read, packet)) + return packet.GetStringRef().size(); + } + else + { + switch (status) { - const char *packet_data = (const char *)event_bytes->GetBytes(); - const uint32_t packet_size = event_bytes->GetByteSize(); - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); - if (log) - log->Printf ("read packet: %.*s", packet_size, packet_data); - if (packet_data && packet_size > 0) - { - std::string &packet_str = packet.GetStringRef(); - if (packet_data[0] == '$') - { - bool success = false; - if (packet_size < 4) - ::fprintf (stderr, "Packet that starts with $ is too short: '%s'\n", packet_data); - else if (packet_data[packet_size-3] != '#' || - !::isxdigit (packet_data[packet_size-2]) || - !::isxdigit (packet_data[packet_size-1])) - ::fprintf (stderr, "Invalid checksum footer for packet: '%s'\n", packet_data); - else - success = true; - - if (success) - packet_str.assign (packet_data + 1, packet_size - 4); - if (GetSendAcks ()) - { - if (success) - { - char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16); - char actual_checksum = CalculcateChecksum (&packet_str[0], packet_str.size()); - checksum_error = packet_checksum != actual_checksum; - } - // Send the ack or nack if needed - if (checksum_error || !success) - SendNack(); - else - SendAck(); - } - } - else - { - packet_str.assign (packet_data, packet_size); - } - return packet_str.size(); - } + case eConnectionStatusSuccess: + break; + + case eConnectionStatusEndOfFile: + case eConnectionStatusNoConnection: + case eConnectionStatusLostConnection: + case eConnectionStatusError: + Disconnect(); + break; + + case eConnectionStatusTimedOut: + timed_out = true; + break; } } - else if (event_type | Communication::eBroadcastBitReadThreadDidExit) - { - // Our read thread exited on us so just fall through and return zero... - Disconnect(); - } } + packet.Clear (); return 0; } -void -GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast, - ConnectionStatus status) +bool +GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, StringExtractorGDBRemote &packet) { // Put the packet data into the buffer in a thread safe fashion Mutex::Locker locker(m_bytes_mutex); - m_bytes.append ((const char *)src, src_len); + if (src && src_len > 0) + m_bytes.append ((const char *)src, src_len); // Parse up the packets into gdb remote packets while (!m_bytes.empty()) @@ -286,29 +242,40 @@ GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, // end_idx must be one past the last valid packet byte. Start // it off with an invalid value that is the same as the current // index. - size_t end_idx = 0; + size_t content_start = 0; + size_t content_length = 0; + size_t total_length = 0; + size_t checksum_idx = std::string::npos; switch (m_bytes[0]) { case '+': // Look for ack case '-': // Look for cancel case '\x03': // ^C to halt target - end_idx = 1; // The command is one byte long... + content_length = total_length = 1; // The command is one byte long... break; case '$': // Look for a standard gdb packet? - end_idx = m_bytes.find('#'); - if (end_idx != std::string::npos) { - if (end_idx + 2 < m_bytes.size()) + size_t hash_pos = m_bytes.find('#'); + if (hash_pos != std::string::npos) { - end_idx += 3; - } - else - { - // Checksum bytes aren't all here yet - end_idx = std::string::npos; + if (hash_pos + 2 < m_bytes.size()) + { + checksum_idx = hash_pos + 1; + // Skip the dollar sign + content_start = 1; + // Don't include the # in the content or the $ in the content length + content_length = hash_pos - 1; + + total_length = hash_pos + 3; // Skip the # and the two hex checksum bytes + } + else + { + // Checksum bytes aren't all here yet + content_length = std::string::npos; + } } } break; @@ -317,27 +284,76 @@ GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, break; } - if (end_idx == std::string::npos) + LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); + if (content_length == std::string::npos) { - //ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE, "GDBRemoteCommunication::%s packet not yet complete: '%s'",__FUNCTION__, m_bytes.c_str()); - return; + packet.Clear(); + return false; } - else if (end_idx > 0) + else if (content_length > 0) { + // We have a valid packet... - assert (end_idx <= m_bytes.size()); - std::auto_ptr event_bytes_ap (new EventDataBytes (&m_bytes[0], end_idx)); - ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "got full packet: %s", event_bytes_ap->GetBytes()); - BroadcastEvent (eBroadcastBitPacketAvailable, event_bytes_ap.release()); - m_bytes.erase(0, end_idx); + assert (content_length <= m_bytes.size()); + assert (total_length <= m_bytes.size()); + assert (content_length <= total_length); + + bool success = true; + std::string &packet_str = packet.GetStringRef(); + packet_str.assign (m_bytes, content_start, content_length); + if (m_bytes[0] == '$') + { + assert (checksum_idx < m_bytes.size()); + if (::isxdigit (m_bytes[checksum_idx+0]) || + ::isxdigit (m_bytes[checksum_idx+1])) + { + if (GetSendAcks ()) + { + const char *packet_checksum_cstr = &m_bytes[checksum_idx]; + char packet_checksum = strtol (packet_checksum_cstr, NULL, 16); + char actual_checksum = CalculcateChecksum (packet_str.c_str(), packet_str.size()); + success = packet_checksum == actual_checksum; + if (!success) + { + if (log) + log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x", + (int)(total_length), + m_bytes.c_str(), + (uint8_t)packet_checksum, + (uint8_t)actual_checksum); + } + // Send the ack or nack if needed + if (!success) + SendNack(); + else + SendAck(); + } + if (success) + { + if (log) + log->Printf ("read packet: %.*s", (int)(total_length), m_bytes.c_str()); + } + } + else + { + success = false; + if (log) + log->Printf ("error: invalid checksum in packet: '%s'\n", (int)(total_length), m_bytes.c_str()); + } + } + m_bytes.erase(0, total_length); + packet.SetFilePos(0); + return success; } else { - assert (1 <= m_bytes.size()); - ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "GDBRemoteCommunication::%s tossing junk byte at %c",__FUNCTION__, m_bytes[0]); + if (log) + log->Printf ("GDBRemoteCommunication::%s tossing junk byte at %c",__FUNCTION__, m_bytes[0]); m_bytes.erase(0, 1); } } + packet.Clear(); + return false; } Error diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index 77e3e1a5d7c7..addec5bd069e 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -56,14 +56,8 @@ public: // Wait for a packet within 'nsec' seconds size_t - WaitForPacket (StringExtractorGDBRemote &response, - uint32_t sec); - - // Wait for a packet with an absolute timeout time. If 'timeout' is NULL - // wait indefinitely. - size_t - WaitForPacket (StringExtractorGDBRemote &response, - const lldb_private::TimeValue* timeout); + WaitForPacketWithTimeoutMicroSeconds (StringExtractorGDBRemote &response, + uint32_t usec); char GetAck (); @@ -81,12 +75,10 @@ public: bool GetSequenceMutex(lldb_private::Mutex::Locker& locker); - //------------------------------------------------------------------ - // Communication overrides - //------------------------------------------------------------------ - virtual void - AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast, lldb::ConnectionStatus status); - + bool + CheckForPacket (const uint8_t *src, + size_t src_len, + StringExtractorGDBRemote &packet); bool IsRunning() const { @@ -121,6 +113,11 @@ public: return old_packet_timeout; } + uint32_t + GetPacketTimeoutInMicroSeconds () const + { + return m_packet_timeout * USEC_PER_SEC; + } //------------------------------------------------------------------ // Start a debugserver instance on the current host using the // supplied connection URL. @@ -130,6 +127,7 @@ public: const char *unix_socket_name, lldb_private::ProcessLaunchInfo &launch_info); + protected: typedef std::list packet_collection; @@ -138,8 +136,8 @@ protected: size_t payload_length); size_t - WaitForPacketNoLock (StringExtractorGDBRemote &response, - const lldb_private::TimeValue* timeout_ptr); + WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &response, + uint32_t timeout_usec); bool WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr); @@ -148,7 +146,6 @@ protected: // Classes that inherit from GDBRemoteCommunication can see and modify these //------------------------------------------------------------------ uint32_t m_packet_timeout; - lldb_private::Listener m_rx_packet_listener; lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time lldb_private::Predicate m_public_is_running; lldb_private::Predicate m_private_is_running; diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index d1c51eca638d..b648ac1ae1cb 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -68,9 +68,6 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) : m_os_version_minor (UINT32_MAX), m_os_version_update (UINT32_MAX) { - m_rx_packet_listener.StartListeningForEvents(this, - Communication::eBroadcastBitPacketAvailable | - Communication::eBroadcastBitReadThreadDidExit); } //---------------------------------------------------------------------- @@ -78,14 +75,8 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) : //---------------------------------------------------------------------- GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() { - m_rx_packet_listener.StopListeningForEvents(this, - Communication::eBroadcastBitPacketAvailable | - Communication::eBroadcastBitReadThreadDidExit); if (IsConnected()) - { - StopReadThread(); Disconnect(); - } } bool @@ -94,7 +85,7 @@ GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr) // Start the read thread after we send the handshake ack since if we // fail to send the handshake ack, there is no reason to continue... if (SendAck()) - return StartReadThread (error_ptr); + return true; if (error_ptr) error_ptr->SetErrorString("failed to send the handshake ack"); @@ -245,15 +236,12 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse ) { Mutex::Locker locker; - TimeValue timeout_time; - timeout_time = TimeValue::Now(); - timeout_time.OffsetWithSeconds (m_packet_timeout); LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); if (GetSequenceMutex (locker)) { if (SendPacketNoLock (payload, payload_length)) - return WaitForPacketNoLock (response, &timeout_time); + return WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ()); } else { @@ -272,6 +260,10 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse { if (sent_interrupt) { + TimeValue timeout_time; + timeout_time = TimeValue::Now(); + timeout_time.OffsetWithSeconds (m_packet_timeout); + if (log) log->Printf ("async: sent interrupt"); if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out)) @@ -380,7 +372,7 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse if (log) log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%.*s)", __FUNCTION__); - if (WaitForPacket (response, (TimeValue*)NULL)) + if (WaitForPacketWithTimeoutMicroSeconds (response, UINT32_MAX)) { if (response.Empty()) state = eStateInvalid; @@ -1662,13 +1654,9 @@ GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector &thr sequence_mutex_unavailable = false; StringExtractorGDBRemote response; - TimeValue timeout_time; - timeout_time = TimeValue::Now(); - timeout_time.OffsetWithSeconds (m_packet_timeout*2); // We will always send at least two packets here... - - for (SendPacketNoLock ("qfThreadInfo", strlen("qfThreadInfo")) && WaitForPacketNoLock (response, &timeout_time); + for (SendPacketNoLock ("qfThreadInfo", strlen("qfThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ()); response.IsNormalResponse(); - SendPacketNoLock ("qsThreadInfo", strlen("qsThreadInfo")) && WaitForPacketNoLock (response, &timeout_time)) + SendPacketNoLock ("qsThreadInfo", strlen("qsThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ())) { char ch = response.GetChar(); if (ch == 'l') diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index 9379077335d8..0619c1076557 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -78,13 +78,13 @@ GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() //} // bool -GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout_ptr, +GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec, Error &error, bool &interrupt, bool &quit) { StringExtractorGDBRemote packet; - if (WaitForPacketNoLock (packet, timeout_ptr)) + if (WaitForPacketWithTimeoutMicroSeconds(packet, timeout_usec)) { const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType (); switch (packet_type) @@ -199,9 +199,7 @@ GDBRemoteCommunicationServer::SendOKResponse () bool GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr) { - if (StartReadThread(error_ptr)) - return GetAck(); - return false; + return GetAck(); } bool @@ -517,7 +515,7 @@ AcceptPortFromInferior (void *arg) char pid_str[256]; ::memset (pid_str, 0, sizeof(pid_str)); ConnectionStatus status; - const size_t pid_str_len = file_conn.Read (pid_str, sizeof(pid_str), status, NULL); + const size_t pid_str_len = file_conn.Read (pid_str, sizeof(pid_str), NULL, status, NULL); if (pid_str_len > 0) { int pid = atoi (pid_str); diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h index 1fddaeb5fea3..cce0e4e64c1e 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h @@ -37,7 +37,7 @@ public: ~GDBRemoteCommunicationServer(); bool - GetPacketAndSendResponse (const lldb_private::TimeValue* timeout_ptr, + GetPacketAndSendResponse (uint32_t timeout_usec, lldb_private::Error &error, bool &interrupt, bool &quit); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index fa2d003c966a..9131bf54bb83 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2273,10 +2273,16 @@ SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, boo { // We found a type pointer, now find the shared pointer form our type list TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID())); - assert (type_sp.get() != NULL); - types.InsertUnique (type_sp); - if (types.GetSize() >= max_matches) - break; + if (type_sp) + { + types.InsertUnique (type_sp); + if (types.GetSize() >= max_matches) + break; + } + else + { + fprintf (stderr, "error: can't find shared pointer for type 0x%8.8x.\n", matching_type->GetID()); + } } } return types.GetSize() - initial_types_size; @@ -4170,7 +4176,6 @@ SymbolFileDWARF::ParseVariables if (orig_die == NULL) return 0; - size_t vars_added = 0; const DWARFDebugInfoEntry *die = orig_die; const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die); dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; @@ -4189,8 +4194,12 @@ SymbolFileDWARF::ParseVariables } else { - assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context..."); - vars_added = 0; + fprintf (stderr, + "error: parent 0x%8.8x %s with no valid compile unit in symbol context for 0x%8.8x %s.\n", + sc_parent_die->GetOffset(), + DW_TAG_value_to_name (parent_tag), + orig_die->GetOffset(), + DW_TAG_value_to_name (orig_die->Tag())); } break; @@ -4202,71 +4211,91 @@ SymbolFileDWARF::ParseVariables // Check to see if we already have parsed the variables for the given scope Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset()); - assert (block != NULL); - variables = block->GetVariableList(false, false); - if (variables.get() == NULL) + if (block != NULL) { - variables.reset(new VariableList()); - block->SetVariableList(variables); + variables = block->GetVariableList(false, false); + if (variables.get() == NULL) + { + variables.reset(new VariableList()); + block->SetVariableList(variables); + } + } + else + { + fprintf (stderr, + "error: NULL block for 0x%8.8x %s for variable at 0x%8.8x %s\n", + sc_parent_die->GetOffset(), + DW_TAG_value_to_name (parent_tag), + orig_die->GetOffset(), + DW_TAG_value_to_name (orig_die->Tag())); } } else { - assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context..."); - vars_added = 0; + fprintf (stderr, + "error: parent 0x%8.8x %s with no valid function in symbol context for 0x%8.8x %s.\n", + sc_parent_die->GetOffset(), + DW_TAG_value_to_name (parent_tag), + orig_die->GetOffset(), + DW_TAG_value_to_name (orig_die->Tag())); } break; default: - assert(!"Didn't find appropriate parent DIE for variable list..."); + fprintf (stderr, + "error: didn't find appropriate parent DIE for variable list for 0x%8.8x %s.\n", + orig_die->GetOffset(), + DW_TAG_value_to_name (orig_die->Tag())); break; } // We need to have a variable list at this point that we can add variables to - assert(variables.get()); - - while (die != NULL) + if (variables.get()) { - dw_tag_t tag = die->Tag(); + size_t vars_added = 0; + while (die != NULL) + { + dw_tag_t tag = die->Tag(); - // Check to see if we have already parsed this variable or constant? - if (m_die_to_variable_sp[die]) - { - if (cc_variable_list) - cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]); - } - else - { - // We haven't already parsed it, lets do that now. - if ((tag == DW_TAG_variable) || - (tag == DW_TAG_constant) || - (tag == DW_TAG_formal_parameter && sc.function)) + // Check to see if we have already parsed this variable or constant? + if (m_die_to_variable_sp[die]) { - VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc)); - if (var_sp) + if (cc_variable_list) + cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]); + } + else + { + // We haven't already parsed it, lets do that now. + if ((tag == DW_TAG_variable) || + (tag == DW_TAG_constant) || + (tag == DW_TAG_formal_parameter && sc.function)) { - variables->AddVariableIfUnique (var_sp); - if (cc_variable_list) - cc_variable_list->AddVariableIfUnique (var_sp); - ++vars_added; + VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc)); + if (var_sp) + { + variables->AddVariableIfUnique (var_sp); + if (cc_variable_list) + cc_variable_list->AddVariableIfUnique (var_sp); + ++vars_added; + } } } + + bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram); + + if (!skip_children && parse_children && die->HasChildren()) + { + vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list); + } + + if (parse_siblings) + die = die->GetSibling(); + else + die = NULL; } - - bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram); - - if (!skip_children && parse_children && die->HasChildren()) - { - vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list); - } - - if (parse_siblings) - die = die->GetSibling(); - else - die = NULL; + return vars_added; } - - return vars_added; + return 0; } //------------------------------------------------------------------ diff --git a/lldb/source/Symbol/DWARFCallFrameInfo.cpp b/lldb/source/Symbol/DWARFCallFrameInfo.cpp index 7513d23da155..34e97e6289f2 100644 --- a/lldb/source/Symbol/DWARFCallFrameInfo.cpp +++ b/lldb/source/Symbol/DWARFCallFrameInfo.cpp @@ -300,7 +300,7 @@ DWARFCallFrameInfo::GetFDEIndex () } while (m_cfi_data.ValidOffsetForDataOfSize (offset, 8)) { - dw_offset_t current_entry = offset; + const dw_offset_t current_entry = offset; uint32_t len = m_cfi_data.GetU32 (&offset); dw_offset_t next_entry = current_entry + len + 4; dw_offset_t cie_id = m_cfi_data.GetU32 (&offset); @@ -312,20 +312,29 @@ DWARFCallFrameInfo::GetFDEIndex () continue; } - const CIE *cie = GetCIE (current_entry + 4 - cie_id); - assert (cie != NULL); - - const lldb::addr_t pc_rel_addr = m_section->GetFileAddress(); - const lldb::addr_t text_addr = LLDB_INVALID_ADDRESS; - const lldb::addr_t data_addr = LLDB_INVALID_ADDRESS; - - lldb::addr_t addr = m_cfi_data.GetGNUEHPointer(&offset, cie->ptr_encoding, pc_rel_addr, text_addr, data_addr); - lldb::addr_t length = m_cfi_data.GetGNUEHPointer(&offset, cie->ptr_encoding & DW_EH_PE_MASK_ENCODING, pc_rel_addr, text_addr, data_addr); - FDEEntry fde; - fde.bounds = AddressRange (addr, length, m_objfile.GetSectionList()); - fde.offset = current_entry; - m_fde_index.push_back(fde); + const dw_offset_t cie_offset = current_entry + 4 - cie_id; + const CIE *cie = GetCIE (cie_offset); + if (cie) + { + const lldb::addr_t pc_rel_addr = m_section->GetFileAddress(); + const lldb::addr_t text_addr = LLDB_INVALID_ADDRESS; + const lldb::addr_t data_addr = LLDB_INVALID_ADDRESS; + lldb::addr_t addr = m_cfi_data.GetGNUEHPointer(&offset, cie->ptr_encoding, pc_rel_addr, text_addr, data_addr); + lldb::addr_t length = m_cfi_data.GetGNUEHPointer(&offset, cie->ptr_encoding & DW_EH_PE_MASK_ENCODING, pc_rel_addr, text_addr, data_addr); + FDEEntry fde; + fde.bounds = AddressRange (addr, length, m_objfile.GetSectionList()); + fde.offset = current_entry; + m_fde_index.push_back(fde); + } + else + { + fprintf (stderr, + "error: unable to find CIE at 0x%8.8x for cie_id = 0x%8.8x for entry at 0x%8.8x.\n", + cie_offset, + cie_id, + current_entry); + } offset = next_entry; } std::sort (m_fde_index.begin(), m_fde_index.end()); diff --git a/lldb/tools/lldb-platform/lldb-platform.cpp b/lldb/tools/lldb-platform/lldb-platform.cpp index 2dc54af2f7b0..bc7896b45722 100644 --- a/lldb/tools/lldb-platform/lldb-platform.cpp +++ b/lldb/tools/lldb-platform/lldb-platform.cpp @@ -72,7 +72,7 @@ main (int argc, char *argv[]) StreamSP log_stream_sp; Args log_args; Error error; - std::string listen_host_post; + std::string listen_host_port; char ch; Debugger::Initialize(); @@ -163,7 +163,7 @@ main (int argc, char *argv[]) break; case 'L': - listen_host_post.append (optarg); + listen_host_port.append (optarg); break; } } @@ -181,15 +181,15 @@ main (int argc, char *argv[]) GDBRemoteCommunicationServer gdb_server (true); - if (!listen_host_post.empty()) + if (!listen_host_port.empty()) { std::auto_ptr conn_ap(new ConnectionFileDescriptor()); if (conn_ap.get()) { std::string connect_url ("listen://"); - connect_url.append(listen_host_post.c_str()); + connect_url.append(listen_host_port.c_str()); - printf ("Listening for a connection on %s...\n", listen_host_post.c_str()); + printf ("Listening for a connection on %s...\n", listen_host_port.c_str()); if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess) { printf ("Connection established.\n"); @@ -208,7 +208,7 @@ main (int argc, char *argv[]) bool done = false; while (!interrupt && !done) { - if (!gdb_server.GetPacketAndSendResponse(NULL, error, interrupt, done)) + if (!gdb_server.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done)) break; } }