@@ -89,6 +89,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
89
89
m_supports_jGetSharedCacheInfo(eLazyBoolCalculate),
90
90
m_supports_QPassSignals(eLazyBoolCalculate),
91
91
m_supports_error_string_reply(eLazyBoolCalculate),
92
+ m_supports_multiprocess(eLazyBoolCalculate),
92
93
m_supports_qProcessInfoPID(true ), m_supports_qfProcessInfo(true ),
93
94
m_supports_qUserName(true ), m_supports_qGroupName(true ),
94
95
m_supports_qThreadStopInfo(true ), m_supports_z0(true ),
@@ -292,6 +293,7 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
292
293
m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
293
294
m_attach_or_wait_reply = eLazyBoolCalculate;
294
295
m_avoid_g_packets = eLazyBoolCalculate;
296
+ m_supports_multiprocess = eLazyBoolCalculate;
295
297
m_supports_qXfer_auxv_read = eLazyBoolCalculate;
296
298
m_supports_qXfer_libraries_read = eLazyBoolCalculate;
297
299
m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
@@ -342,11 +344,13 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
342
344
m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
343
345
m_supports_qXfer_features_read = eLazyBoolNo;
344
346
m_supports_qXfer_memory_map_read = eLazyBoolNo;
347
+ m_supports_multiprocess = eLazyBoolNo;
345
348
m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
346
349
// not, we assume no limit
347
350
348
351
// build the qSupported packet
349
- std::vector<std::string> features = {" xmlRegisters=i386,arm,mips,arc" };
352
+ std::vector<std::string> features = {" xmlRegisters=i386,arm,mips,arc" ,
353
+ " multiprocess+" };
350
354
StreamString packet;
351
355
packet.PutCString (" qSupported" );
352
356
for (uint32_t i = 0 ; i < features.size (); ++i) {
@@ -433,6 +437,11 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
433
437
else
434
438
m_supports_QPassSignals = eLazyBoolNo;
435
439
440
+ if (::strstr (response_cstr, " multiprocess+" ))
441
+ m_supports_multiprocess = eLazyBoolYes;
442
+ else
443
+ m_supports_multiprocess = eLazyBoolNo;
444
+
436
445
const char *packet_size_str = ::strstr (response_cstr, " PacketSize=" );
437
446
if (packet_size_str) {
438
447
StringExtractorGDBRemote packet_response (packet_size_str +
@@ -741,12 +750,14 @@ lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
741
750
// If we don't get a response for $qC, check if $qfThreadID gives us a
742
751
// result.
743
752
if (m_curr_pid == LLDB_INVALID_PROCESS_ID) {
744
- std::vector<lldb::tid_t > thread_ids;
745
753
bool sequence_mutex_unavailable;
746
- size_t size;
747
- size = GetCurrentThreadIDs (thread_ids, sequence_mutex_unavailable);
748
- if (size && !sequence_mutex_unavailable) {
749
- m_curr_pid = thread_ids.front ();
754
+ auto ids = GetCurrentProcessAndThreadIDs (sequence_mutex_unavailable);
755
+ if (!ids.empty () && !sequence_mutex_unavailable) {
756
+ // If server returned an explicit PID, use that.
757
+ m_curr_pid = ids.front ().first ;
758
+ // Otherwise, use the TID of the first thread (Linux hack).
759
+ if (m_curr_pid == LLDB_INVALID_PROCESS_ID)
760
+ m_curr_pid = ids.front ().second ;
750
761
m_curr_pid_is_valid = eLazyBoolYes;
751
762
return m_curr_pid;
752
763
}
@@ -1125,8 +1136,23 @@ bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
1125
1136
if (!response.IsNormalResponse ())
1126
1137
return false ;
1127
1138
1128
- if (response.GetChar () == ' Q' && response.GetChar () == ' C' )
1129
- tid = response.GetHexMaxU64 (true , -1 );
1139
+ if (response.GetChar () == ' Q' && response.GetChar () == ' C' ) {
1140
+ auto pid_tid = response.GetPidTid (0 );
1141
+ if (!pid_tid)
1142
+ return false ;
1143
+
1144
+ lldb::pid_t pid = pid_tid->first ;
1145
+ // invalid
1146
+ if (pid == StringExtractorGDBRemote::AllProcesses)
1147
+ return false ;
1148
+
1149
+ // if we get pid as well, update m_curr_pid
1150
+ if (pid != 0 ) {
1151
+ m_curr_pid = pid;
1152
+ m_curr_pid_is_valid = eLazyBoolYes;
1153
+ }
1154
+ tid = pid_tid->second ;
1155
+ }
1130
1156
1131
1157
return true ;
1132
1158
}
@@ -2766,9 +2792,10 @@ uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
2766
2792
return UINT8_MAX;
2767
2793
}
2768
2794
2769
- size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs (
2770
- std::vector<lldb::tid_t > &thread_ids, bool &sequence_mutex_unavailable) {
2771
- thread_ids.clear ();
2795
+ std::vector<std::pair<lldb::pid_t , lldb::tid_t >>
2796
+ GDBRemoteCommunicationClient::GetCurrentProcessAndThreadIDs (
2797
+ bool &sequence_mutex_unavailable) {
2798
+ std::vector<std::pair<lldb::pid_t , lldb::tid_t >> ids;
2772
2799
2773
2800
Lock lock (*this , false );
2774
2801
if (lock) {
@@ -2786,11 +2813,11 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
2786
2813
break ;
2787
2814
if (ch == ' m' ) {
2788
2815
do {
2789
- tid_t tid = response.GetHexMaxU64 (false , LLDB_INVALID_THREAD_ID);
2816
+ auto pid_tid = response.GetPidTid (LLDB_INVALID_PROCESS_ID);
2817
+ if (!pid_tid)
2818
+ return {};
2790
2819
2791
- if (tid != LLDB_INVALID_THREAD_ID) {
2792
- thread_ids.push_back (tid);
2793
- }
2820
+ ids.push_back (pid_tid.getValue ());
2794
2821
ch = response.GetChar (); // Skip the command separator
2795
2822
} while (ch == ' ,' ); // Make sure we got a comma separator
2796
2823
}
@@ -2803,10 +2830,10 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
2803
2830
* be as simple as 'S05'. There is no packet which can give us pid and/or
2804
2831
* tid.
2805
2832
* Assume pid=tid=1 in such cases.
2806
- */
2833
+ */
2807
2834
if ((response.IsUnsupportedResponse () || response.IsNormalResponse ()) &&
2808
- thread_ids .size () == 0 && IsConnected ()) {
2809
- thread_ids. push_back ( 1 );
2835
+ ids .size () == 0 && IsConnected ()) {
2836
+ ids. emplace_back ( 1 , 1 );
2810
2837
}
2811
2838
} else {
2812
2839
Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS |
@@ -2815,6 +2842,28 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
2815
2842
" packet 'qfThreadInfo'" );
2816
2843
sequence_mutex_unavailable = true ;
2817
2844
}
2845
+
2846
+ return ids;
2847
+ }
2848
+
2849
+ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs (
2850
+ std::vector<lldb::tid_t > &thread_ids, bool &sequence_mutex_unavailable) {
2851
+ lldb::pid_t pid = GetCurrentProcessID ();
2852
+ thread_ids.clear ();
2853
+
2854
+ auto ids = GetCurrentProcessAndThreadIDs (sequence_mutex_unavailable);
2855
+ if (ids.empty () || sequence_mutex_unavailable)
2856
+ return 0 ;
2857
+
2858
+ for (auto id : ids) {
2859
+ // skip threads that do not belong to the current process
2860
+ if (id.first != LLDB_INVALID_PROCESS_ID && id.first != pid)
2861
+ continue ;
2862
+ if (id.second != LLDB_INVALID_THREAD_ID &&
2863
+ id.second != StringExtractorGDBRemote::AllThreads)
2864
+ thread_ids.push_back (id.second );
2865
+ }
2866
+
2818
2867
return thread_ids.size ();
2819
2868
}
2820
2869
0 commit comments