diff options
author | dim <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 |
commit | 66b75430a93929d6fc6ed63db14ca28e3ad5b1f6 (patch) | |
tree | 9ed5e1a91f242e2cb5911577356e487a55c01b78 /source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp | |
parent | 23814158e5384f73c6fa951b66d5f807f9c24a2b (diff) | |
download | FreeBSD-src-66b75430a93929d6fc6ed63db14ca28e3ad5b1f6.zip FreeBSD-src-66b75430a93929d6fc6ed63db14ca28e3ad5b1f6.tar.gz |
Vendor import of stripped lldb trunk r256633:
https://llvm.org/svn/llvm-project/lldb/trunk@256633
Diffstat (limited to 'source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp')
-rw-r--r-- | source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp | 287 |
1 files changed, 190 insertions, 97 deletions
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index b8c67c5..5c7f6ca 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -619,7 +619,6 @@ GDBRemoteCommunicationClient::GetThreadsInfo() if (m_supports_jThreadsInfo) { StringExtractorGDBRemote response; - m_supports_jThreadExtendedInfo = eLazyBoolNo; if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) == PacketResult::Success) { if (response.IsUnsupportedResponse()) @@ -782,7 +781,7 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); // In order to stop async notifications from being processed in the middle of the - // send/recieve sequence Hijack the broadcast. Then rebroadcast any events when we are done. + // send/receive sequence Hijack the broadcast. Then rebroadcast any events when we are done. static Listener hijack_listener("lldb.NotifyHijacker"); HijackBroadcaster(&hijack_listener, eBroadcastBitGdbReadThreadGotNotify); @@ -878,10 +877,10 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse } } - // Remove our Hijacking listner from the broadcast. + // Remove our Hijacking listener from the broadcast. RestoreBroadcaster(); - // If a notification event occured, rebroadcast since it can now be processed safely. + // If a notification event occurred, rebroadcast since it can now be processed safely. EventSP event_sp; if (hijack_listener.GetNextEvent(event_sp)) BroadcastEvent(event_sp); @@ -1050,7 +1049,6 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse Mutex::Locker locker(m_sequence_mutex); StateType state = eStateRunning; - BroadcastEvent(eBroadcastBitRunPacketSent, NULL); m_public_is_running.SetValue (true, eBroadcastNever); // Set the starting continue packet into "continue_packet". This packet // may change if we are interrupted and we continue after an async packet... @@ -1060,6 +1058,7 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse const auto sigint_signo = process->GetUnixSignals()->GetSignalNumberFromName("SIGINT"); bool got_async_packet = false; + bool broadcast_sent = false; while (state == eStateRunning) { @@ -1072,6 +1071,12 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse else m_interrupt_sent = false; + if (! broadcast_sent) + { + BroadcastEvent(eBroadcastBitRunPacketSent, NULL); + broadcast_sent = true; + } + m_private_is_running.SetValue (true, eBroadcastAlways); } @@ -1133,10 +1138,10 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse continue_after_async = false; // We didn't get a SIGINT or SIGSTOP, so try for a - // very brief time (1 ms) to get another stop reply + // very brief time (0.1s) to get another stop reply // packet to make sure it doesn't get in the way StringExtractorGDBRemote extra_stop_reply_packet; - uint32_t timeout_usec = 1000; + uint32_t timeout_usec = 100000; if (ReadPacket (extra_stop_reply_packet, timeout_usec, false) == PacketResult::Success) { switch (extra_stop_reply_packet.GetChar()) @@ -1262,9 +1267,13 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse got_async_packet = true; std::string inferior_stdout; inferior_stdout.reserve(response.GetBytesLeft () / 2); - char ch; - while ((ch = response.GetHexU8()) != '\0') - inferior_stdout.append(1, ch); + + uint8_t ch; + while (response.GetHexU8Ex(ch)) + { + if (ch != 0) + inferior_stdout.append(1, (char)ch); + } process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size()); } break; @@ -1574,6 +1583,8 @@ GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_valu { case '$': case '#': + case '*': + case '}': send_hex_encoding = true; break; default: @@ -2308,7 +2319,8 @@ GDBRemoteCommunicationClient::Detach (bool keep_stopped) const int packet_len = ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:"); assert (packet_len < (int)sizeof(packet)); StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success) + if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success + && response.IsOKResponse()) { m_supports_detach_stay_stopped = eLazyBoolYes; } @@ -2326,7 +2338,7 @@ GDBRemoteCommunicationClient::Detach (bool keep_stopped) else { StringExtractorGDBRemote response; - PacketResult packet_result = SendPacketAndWaitForResponse ("D1", 1, response, false); + PacketResult packet_result = SendPacketAndWaitForResponse ("D1", 2, response, false); if (packet_result != PacketResult::Success) error.SetErrorString ("Sending extended disconnect packet failed."); } @@ -3311,10 +3323,16 @@ GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success; } -uint16_t -GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid, const char *remote_accept_hostname) +bool +GDBRemoteCommunicationClient::LaunchGDBServer (const char *remote_accept_hostname, + lldb::pid_t &pid, + uint16_t &port, + std::string &socket_name) { pid = LLDB_INVALID_PROCESS_ID; + port = 0; + socket_name.clear(); + StringExtractorGDBRemote response; StreamString stream; stream.PutCString("qLaunchGDBServer;"); @@ -3339,22 +3357,67 @@ GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid, const // give the process a few seconds to startup GDBRemoteCommunication::ScopedTimeout timeout (*this, 10); - + if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) { std::string name; std::string value; - uint16_t port = 0; + StringExtractor extractor; while (response.GetNameColonValue(name, value)) { if (name.compare("port") == 0) port = StringConvert::ToUInt32(value.c_str(), 0, 0); else if (name.compare("pid") == 0) pid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0); + else if (name.compare("socket_name") == 0) + { + extractor.GetStringRef().swap(value); + extractor.SetFilePos(0); + extractor.GetHexByteString(value); + + socket_name = value; + } } - return port; + return true; } - return 0; + return false; +} + +size_t +GDBRemoteCommunicationClient::QueryGDBServer (std::vector<std::pair<uint16_t, std::string>>& connection_urls) +{ + connection_urls.clear(); + + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) != PacketResult::Success) + return 0; + + StructuredData::ObjectSP data = StructuredData::ParseJSON(response.GetStringRef()); + if (!data) + return 0; + + StructuredData::Array* array = data->GetAsArray(); + if (!array) + return 0; + + for (size_t i = 0, count = array->GetSize(); i < count; ++i) + { + StructuredData::Dictionary* element = nullptr; + if (!array->GetItemAtIndexAsDictionary(i, element)) + continue; + + uint16_t port = 0; + if (StructuredData::ObjectSP port_osp = element->GetValueForKey(llvm::StringRef("port"))) + port = port_osp->GetIntegerValue(0); + + std::string socket_name; + if (StructuredData::ObjectSP socket_name_osp = element->GetValueForKey(llvm::StringRef("socket_name"))) + socket_name = socket_name_osp->GetStringValue(); + + if (port != 0 || !socket_name.empty()) + connection_urls.emplace_back(port, socket_name); + } + return connection_urls.size(); } bool @@ -3395,6 +3458,17 @@ GDBRemoteCommunicationClient::SetCurrentThread (uint64_t tid) m_curr_tid = tid; return true; } + + /* + * Connected bare-iron target (like YAMON gdb-stub) may not have support for Hg packet. + * The reply from '?' packet could be as simple as 'S05'. There is no packet which can + * give us pid and/or tid. Assume pid=tid=1 in such cases. + */ + if (response.IsUnsupportedResponse() && IsConnected()) + { + m_curr_tid = 1; + return true; + } } return false; } @@ -3421,6 +3495,17 @@ GDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid) m_curr_tid_run = tid; return true; } + + /* + * Connected bare-iron target (like YAMON gdb-stub) may not have support for Hc packet. + * The reply from '?' packet could be as simple as 'S05'. There is no packet which can + * give us pid and/or tid. Assume pid=tid=1 in such cases. + */ + if (response.IsUnsupportedResponse() && IsConnected()) + { + m_curr_tid_run = 1; + return true; + } } return false; } @@ -3546,6 +3631,17 @@ GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thr } while (ch == ','); // Make sure we got a comma separator } } + + /* + * Connected bare-iron target (like YAMON gdb-stub) may not have support for + * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet could + * be as simple as 'S05'. There is no packet which can give us pid and/or tid. + * Assume pid=tid=1 in such cases. + */ + if (response.IsUnsupportedResponse() && thread_ids.size() == 0 && IsConnected()) + { + thread_ids.push_back (1); + } } else { @@ -4347,100 +4443,97 @@ GDBRemoteCommunicationClient::ServeSymbolLookups(lldb_private::Process *process) { StreamString packet; packet.PutCString ("qSymbol::"); - while (1) + StringExtractorGDBRemote response; + while (SendPacketAndWaitForResponseNoLock(packet.GetData(), packet.GetSize(), response) == PacketResult::Success) { - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponseNoLock(packet.GetData(), packet.GetSize(), response) == PacketResult::Success) + if (response.IsOKResponse()) { - if (response.IsOKResponse()) - { - // We are done serving symbols requests - return; - } + // We are done serving symbols requests + return; + } - if (response.IsUnsupportedResponse()) - { - // qSymbol is not supported by the current GDB server we are connected to - m_supports_qSymbol = false; - return; - } - else + if (response.IsUnsupportedResponse()) + { + // qSymbol is not supported by the current GDB server we are connected to + m_supports_qSymbol = false; + return; + } + else + { + llvm::StringRef response_str(response.GetStringRef()); + if (response_str.startswith("qSymbol:")) { - llvm::StringRef response_str(response.GetStringRef()); - if (response_str.startswith("qSymbol:")) + response.SetFilePos(strlen("qSymbol:")); + std::string symbol_name; + if (response.GetHexByteString(symbol_name)) { - response.SetFilePos(strlen("qSymbol:")); - std::string symbol_name; - if (response.GetHexByteString(symbol_name)) - { - if (symbol_name.empty()) - return; + if (symbol_name.empty()) + return; - addr_t symbol_load_addr = LLDB_INVALID_ADDRESS; - lldb_private::SymbolContextList sc_list; - if (process->GetTarget().GetImages().FindSymbolsWithNameAndType(ConstString(symbol_name), eSymbolTypeAny, sc_list)) + addr_t symbol_load_addr = LLDB_INVALID_ADDRESS; + lldb_private::SymbolContextList sc_list; + if (process->GetTarget().GetImages().FindSymbolsWithNameAndType(ConstString(symbol_name), eSymbolTypeAny, sc_list)) + { + const size_t num_scs = sc_list.GetSize(); + for (size_t sc_idx=0; sc_idx<num_scs && symbol_load_addr == LLDB_INVALID_ADDRESS; ++sc_idx) { - const size_t num_scs = sc_list.GetSize(); - for (size_t sc_idx=0; sc_idx<num_scs && symbol_load_addr == LLDB_INVALID_ADDRESS; ++sc_idx) + SymbolContext sc; + if (sc_list.GetContextAtIndex(sc_idx, sc)) { - SymbolContext sc; - if (sc_list.GetContextAtIndex(sc_idx, sc)) + if (sc.symbol) { - if (sc.symbol) + switch (sc.symbol->GetType()) { - switch (sc.symbol->GetType()) - { - case eSymbolTypeInvalid: - case eSymbolTypeAbsolute: - case eSymbolTypeUndefined: - case eSymbolTypeSourceFile: - case eSymbolTypeHeaderFile: - case eSymbolTypeObjectFile: - case eSymbolTypeCommonBlock: - case eSymbolTypeBlock: - case eSymbolTypeLocal: - case eSymbolTypeParam: - case eSymbolTypeVariable: - case eSymbolTypeVariableType: - case eSymbolTypeLineEntry: - case eSymbolTypeLineHeader: - case eSymbolTypeScopeBegin: - case eSymbolTypeScopeEnd: - case eSymbolTypeAdditional: - case eSymbolTypeCompiler: - case eSymbolTypeInstrumentation: - case eSymbolTypeTrampoline: - break; - - case eSymbolTypeCode: - case eSymbolTypeResolver: - case eSymbolTypeData: - case eSymbolTypeRuntime: - case eSymbolTypeException: - case eSymbolTypeObjCClass: - case eSymbolTypeObjCMetaClass: - case eSymbolTypeObjCIVar: - case eSymbolTypeReExported: - symbol_load_addr = sc.symbol->GetLoadAddress(&process->GetTarget()); - break; - } + case eSymbolTypeInvalid: + case eSymbolTypeAbsolute: + case eSymbolTypeUndefined: + case eSymbolTypeSourceFile: + case eSymbolTypeHeaderFile: + case eSymbolTypeObjectFile: + case eSymbolTypeCommonBlock: + case eSymbolTypeBlock: + case eSymbolTypeLocal: + case eSymbolTypeParam: + case eSymbolTypeVariable: + case eSymbolTypeVariableType: + case eSymbolTypeLineEntry: + case eSymbolTypeLineHeader: + case eSymbolTypeScopeBegin: + case eSymbolTypeScopeEnd: + case eSymbolTypeAdditional: + case eSymbolTypeCompiler: + case eSymbolTypeInstrumentation: + case eSymbolTypeTrampoline: + break; + + case eSymbolTypeCode: + case eSymbolTypeResolver: + case eSymbolTypeData: + case eSymbolTypeRuntime: + case eSymbolTypeException: + case eSymbolTypeObjCClass: + case eSymbolTypeObjCMetaClass: + case eSymbolTypeObjCIVar: + case eSymbolTypeReExported: + symbol_load_addr = sc.symbol->GetLoadAddress(&process->GetTarget()); + break; } } } } - // This is the normal path where our symbol lookup was successful and we want - // to send a packet with the new symbol value and see if another lookup needs to be - // done. - - // Change "packet" to contain the requested symbol value and name - packet.Clear(); - packet.PutCString("qSymbol:"); - if (symbol_load_addr != LLDB_INVALID_ADDRESS) - packet.Printf("%" PRIx64, symbol_load_addr); - packet.PutCString(":"); - packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size()); - continue; // go back to the while loop and send "packet" and wait for another response } + // This is the normal path where our symbol lookup was successful and we want + // to send a packet with the new symbol value and see if another lookup needs to be + // done. + + // Change "packet" to contain the requested symbol value and name + packet.Clear(); + packet.PutCString("qSymbol:"); + if (symbol_load_addr != LLDB_INVALID_ADDRESS) + packet.Printf("%" PRIx64, symbol_load_addr); + packet.PutCString(":"); + packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size()); + continue; // go back to the while loop and send "packet" and wait for another response } } } |