@@ -24,618 +24,281 @@ using namespace lldb_private::process_linux;
24
24
25
25
// ===----------------------------------------------------------------------===//
26
26
27
- class ThreadStateCoordinator ::EventBase : public std::enable_shared_from_this<ThreadStateCoordinator::EventBase>
28
- {
29
- public:
30
- EventBase ()
31
- {
32
- }
33
-
34
- virtual
35
- ~EventBase ()
36
- {
37
- }
38
-
39
- virtual std::string
40
- GetDescription () = 0 ;
41
-
42
- // Return false if the coordinator should terminate running.
43
- virtual EventLoopResult
44
- ProcessEvent (ThreadStateCoordinator &coordinator) = 0 ;
45
- };
46
-
47
- // ===----------------------------------------------------------------------===//
48
-
49
- class ThreadStateCoordinator ::EventCallAfterThreadsStop : public ThreadStateCoordinator::EventBase
27
+ void
28
+ ThreadStateCoordinator::DoResume (
29
+ lldb::tid_t tid,
30
+ ResumeThreadFunction request_thread_resume_function,
31
+ ErrorFunction error_function,
32
+ bool error_when_already_running)
50
33
{
51
- public:
52
- EventCallAfterThreadsStop (lldb::tid_t triggering_tid,
53
- const ThreadIDSet &wait_for_stop_tids,
54
- const StopThreadFunction &request_thread_stop_function,
55
- const ThreadIDFunction &call_after_function,
56
- const ErrorFunction &error_function):
57
- EventBase (),
58
- m_triggering_tid (triggering_tid),
59
- m_wait_for_stop_tids (wait_for_stop_tids),
60
- m_original_wait_for_stop_tids (wait_for_stop_tids),
61
- m_request_thread_stop_function (request_thread_stop_function),
62
- m_call_after_function (call_after_function),
63
- m_error_function (error_function),
64
- m_request_stop_on_all_unstopped_threads (false ),
65
- m_skip_stop_request_tids ()
66
- {
67
- }
68
-
69
- EventCallAfterThreadsStop (lldb::tid_t triggering_tid,
70
- const StopThreadFunction &request_thread_stop_function,
71
- const ThreadIDFunction &call_after_function,
72
- const ErrorFunction &error_function) :
73
- EventBase (),
74
- m_triggering_tid (triggering_tid),
75
- m_wait_for_stop_tids (),
76
- m_original_wait_for_stop_tids (),
77
- m_request_thread_stop_function (request_thread_stop_function),
78
- m_call_after_function (call_after_function),
79
- m_error_function (error_function),
80
- m_request_stop_on_all_unstopped_threads (true ),
81
- m_skip_stop_request_tids ()
82
- {
83
- }
84
-
85
- EventCallAfterThreadsStop (lldb::tid_t triggering_tid,
86
- const StopThreadFunction &request_thread_stop_function,
87
- const ThreadIDFunction &call_after_function,
88
- const ThreadIDSet &skip_stop_request_tids,
89
- const ErrorFunction &error_function) :
90
- EventBase (),
91
- m_triggering_tid (triggering_tid),
92
- m_wait_for_stop_tids (),
93
- m_original_wait_for_stop_tids (),
94
- m_request_thread_stop_function (request_thread_stop_function),
95
- m_call_after_function (call_after_function),
96
- m_error_function (error_function),
97
- m_request_stop_on_all_unstopped_threads (true ),
98
- m_skip_stop_request_tids (skip_stop_request_tids)
99
- {
100
- }
101
-
102
- lldb::tid_t GetTriggeringTID () const
103
- {
104
- return m_triggering_tid;
105
- }
106
-
107
- ThreadIDSet &
108
- GetRemainingWaitTIDs ()
109
- {
110
- return m_wait_for_stop_tids;
111
- }
112
-
113
- const ThreadIDSet &
114
- GetRemainingWaitTIDs () const
115
- {
116
- return m_wait_for_stop_tids;
117
- }
118
-
119
-
120
- const ThreadIDSet &
121
- GetInitialWaitTIDs () const
34
+ // Ensure we know about the thread.
35
+ auto find_it = m_tid_map.find (tid);
36
+ if (find_it == m_tid_map.end ())
122
37
{
123
- return m_original_wait_for_stop_tids;
38
+ // We don't know about this thread. This is an error condition.
39
+ std::ostringstream error_message;
40
+ error_message << " error: tid " << tid << " asked to resume but tid is unknown" ;
41
+ error_function (error_message.str ());
42
+ return ;
124
43
}
125
-
126
- EventLoopResult
127
- ProcessEvent (ThreadStateCoordinator &coordinator) override
128
- {
129
- // Validate we know about the deferred trigger thread.
130
- if (!coordinator.IsKnownThread (m_triggering_tid))
131
- {
132
- // We don't know about this thread. This is an error condition.
133
- std::ostringstream error_message;
134
- error_message << " error: deferred notification tid " << m_triggering_tid << " is unknown" ;
135
- m_error_function (error_message.str ());
136
-
137
- // We bail out here.
138
- return eventLoopResultContinue;
139
- }
140
-
141
- if (m_request_stop_on_all_unstopped_threads)
142
- {
143
- RequestStopOnAllRunningThreads (coordinator);
144
- }
145
- else
146
- {
147
- if (!RequestStopOnAllSpecifiedThreads (coordinator))
148
- return eventLoopResultContinue;
149
- }
150
-
151
- if (m_wait_for_stop_tids.empty ())
44
+ auto & context = find_it->second ;
45
+ // Tell the thread to resume if we don't already think it is running.
46
+ const bool is_stopped = context.m_state == ThreadState::Stopped;
47
+ if (!is_stopped)
48
+ {
49
+ // It's not an error, just a log, if the error_when_already_running flag is not set.
50
+ // This covers cases where, for instance, we're just trying to resume all threads
51
+ // from the user side.
52
+ if (!error_when_already_running)
152
53
{
153
- // We're not waiting for any threads. Fire off the deferred signal delivery event.
154
- NotifyNow ();
54
+ Log (" ThreadStateCoordinator::%s tid %" PRIu64 " optional resume skipped since it is already running" ,
55
+ __FUNCTION__,
56
+ tid);
155
57
}
156
58
else
157
59
{
158
- // The real meat of this class: wait until all
159
- // the thread stops (or thread deaths) come in
160
- // before firing off that the triggering signal
161
- // arrived.
162
- coordinator. SetPendingNotification ( shared_from_this ());
60
+ // Skip the resume call - we have tracked it to be running. And we unconditionally
61
+ // expected to resume this thread. Flag this as an error.
62
+ std::ostringstream error_message;
63
+ error_message << " error: tid " << tid << " asked to resume but we think it is already running " ;
64
+ error_function (error_message. str ());
163
65
}
164
66
165
- return eventLoopResultContinue;
67
+ // Error or not, we're done.
68
+ return ;
166
69
}
167
70
168
- // Return true if still pending thread stops waiting; false if no more stops.
169
- // If no more pending stops, signal.
170
- bool
171
- RemoveThreadStopRequirementAndMaybeSignal (lldb::tid_t tid)
71
+ // Before we do the resume below, first check if we have a pending
72
+ // stop notification this is currently or was previously waiting for
73
+ // this thread to stop. This is potentially a buggy situation since
74
+ // we're ostensibly waiting for threads to stop before we send out the
75
+ // pending notification, and here we are resuming one before we send
76
+ // out the pending stop notification.
77
+ if (m_pending_notification_up)
172
78
{
173
- // Remove this tid if it was in it.
174
- m_wait_for_stop_tids.erase (tid);
175
-
176
- // Fire pending notification if no pending thread stops remain.
177
- if (m_wait_for_stop_tids.empty ())
79
+ if (m_pending_notification_up->wait_for_stop_tids .count (tid) > 0 )
178
80
{
179
- // Fire the pending notification now.
180
- NotifyNow ();
181
- return false ;
81
+ Log (" ThreadStateCoordinator::%s about to resume tid %" PRIu64 " per explicit request but we have a pending stop notification (tid %" PRIu64 " ) that is actively waiting for this thread to stop. Valid sequence of events?" , __FUNCTION__, tid, m_pending_notification_up->triggering_tid );
182
82
}
183
-
184
- // Still have pending thread stops.
185
- return true ;
186
- }
187
-
188
- void
189
- AddThreadStopRequirement (lldb::tid_t tid)
190
- {
191
- // Add this tid.
192
- auto insert_result = m_wait_for_stop_tids.insert (tid);
193
-
194
- // If it was really added, send the stop request to it.
195
- if (insert_result.second )
196
- m_request_thread_stop_function (tid);
197
- }
198
-
199
- std::string
200
- GetDescription () override
201
- {
202
- std::ostringstream description;
203
- description << " EventCallAfterThreadsStop (triggering_tid=" << m_triggering_tid << " , request_stop_on_all_unstopped_threads=" << m_request_stop_on_all_unstopped_threads << " , skip_stop_request_tids.size()=" << m_skip_stop_request_tids.size () << " )" ;
204
- return description.str ();
205
- }
206
-
207
- private:
208
-
209
- void
210
- NotifyNow ()
211
- {
212
- m_call_after_function (m_triggering_tid);
213
- }
214
-
215
- bool
216
- RequestStopOnAllSpecifiedThreads (ThreadStateCoordinator &coordinator)
217
- {
218
- // Request a stop for all the thread stops that need to be stopped
219
- // and are not already known to be stopped. Keep a list of all the
220
- // threads from which we still need to hear a stop reply.
221
-
222
- ThreadIDSet sent_tids;
223
- for (auto tid : m_wait_for_stop_tids)
83
+ else if (m_pending_notification_up->original_wait_for_stop_tids .count (tid) > 0 )
224
84
{
225
- // Validate we know about all tids for which we must first receive a stop before
226
- // triggering the deferred stop notification.
227
- auto find_it = coordinator.m_tid_map .find (tid);
228
- if (find_it == coordinator.m_tid_map .end ())
85
+ Log (" ThreadStateCoordinator::%s about to resume tid %" PRIu64 " per explicit request but we have a pending stop notification (tid %" PRIu64 " ) that hasn't fired yet and this is one of the threads we had been waiting on (and already marked satisfied for this tid). Valid sequence of events?" , __FUNCTION__, tid, m_pending_notification_up->triggering_tid );
86
+ for (auto tid : m_pending_notification_up->wait_for_stop_tids )
229
87
{
230
- // This is an error. We shouldn't be asking for waiting pids that aren't known.
231
- // NOTE: we may be stripping out the specification of wait tids and handle this
232
- // automatically, in which case this state can never occur.
233
- std::ostringstream error_message;
234
- error_message << " error: deferred notification for tid " << m_triggering_tid << " specified an unknown/untracked pending stop tid " << m_triggering_tid;
235
- m_error_function (error_message.str ());
236
-
237
- // Bail out here.
238
- return false ;
239
- }
240
-
241
- // If the pending stop thread is currently running, we need to send it a stop request.
242
- auto & context = find_it->second ;
243
- if (context.m_state == ThreadState::Running)
244
- {
245
- RequestThreadStop (tid, coordinator, context);
246
- sent_tids.insert (tid);
88
+ Log (" ThreadStateCoordinator::%s tid %" PRIu64 " deferred stop notification still waiting on tid %" PRIu64,
89
+ __FUNCTION__,
90
+ m_pending_notification_up->triggering_tid ,
91
+ tid);
247
92
}
248
93
}
249
-
250
- // We only need to wait for the sent_tids - so swap our wait set
251
- // to the sent tids. The rest are already stopped and we won't
252
- // be receiving stop notifications for them.
253
- m_wait_for_stop_tids.swap (sent_tids);
254
-
255
- // Succeeded, keep running.
256
- return true ;
257
94
}
258
95
259
- void
260
- RequestStopOnAllRunningThreads (ThreadStateCoordinator &coordinator)
96
+ // Request a resume. We expect this to be synchronous and the system
97
+ // to reflect it is running after this completes.
98
+ const auto error = request_thread_resume_function (tid, false );
99
+ if (error.Success ())
261
100
{
262
- // Request a stop for all the thread stops that need to be stopped
263
- // and are not already known to be stopped. Keep a list of all the
264
- // threads from which we still need to hear a stop reply.
265
-
266
- ThreadIDSet sent_tids;
267
- for (auto it = coordinator.m_tid_map .begin (); it != coordinator.m_tid_map .end (); ++it)
268
- {
269
- // We only care about threads not stopped.
270
- const bool running = it->second .m_state == ThreadState::Running;
271
- if (running)
272
- {
273
- const lldb::tid_t tid = it->first ;
274
-
275
- // Request this thread stop if the tid stop request is not explicitly ignored.
276
- const bool skip_stop_request = m_skip_stop_request_tids.count (tid) > 0 ;
277
- if (!skip_stop_request)
278
- RequestThreadStop (tid, coordinator, it->second );
279
-
280
- // Even if we skipped sending the stop request for other reasons (like stepping),
281
- // we still need to wait for that stepping thread to notify completion/stop.
282
- sent_tids.insert (tid);
283
- }
284
- }
285
-
286
- // Set the wait list to the set of tids for which we requested stops.
287
- m_wait_for_stop_tids.swap (sent_tids);
101
+ // Now mark it is running.
102
+ context.m_state = ThreadState::Running;
103
+ context.m_request_resume_function = request_thread_resume_function;
288
104
}
289
-
290
- void
291
- RequestThreadStop (lldb::tid_t tid, ThreadStateCoordinator &coordinator, ThreadContext& context)
105
+ else
292
106
{
293
- const auto error = m_request_thread_stop_function (tid);
294
- if (error.Success ())
295
- {
296
- context.m_stop_requested = true ;
297
- }
298
- else
299
- {
300
- coordinator.Log (" EventCallAfterThreadsStop::%s failed to request thread stop tid %" PRIu64 " : %s" ,
301
- __FUNCTION__, tid, error.AsCString ());
302
- }
107
+ Log (" ThreadStateCoordinator::%s failed to resume thread tid %" PRIu64 " : %s" ,
108
+ __FUNCTION__, tid, error.AsCString ());
303
109
}
304
110
305
- const lldb::tid_t m_triggering_tid;
306
- ThreadIDSet m_wait_for_stop_tids;
307
- const ThreadIDSet m_original_wait_for_stop_tids;
308
- StopThreadFunction m_request_thread_stop_function;
309
- ThreadIDFunction m_call_after_function;
310
- ErrorFunction m_error_function;
311
- const bool m_request_stop_on_all_unstopped_threads;
312
- ThreadIDSet m_skip_stop_request_tids;
313
- };
111
+ return ;
112
+ }
314
113
315
114
// ===----------------------------------------------------------------------===//
316
115
317
- class ThreadStateCoordinator ::EventReset : public ThreadStateCoordinator::EventBase
116
+ ThreadStateCoordinator::ThreadStateCoordinator (const LogFunction &log_function) :
117
+ m_log_function (log_function),
118
+ m_tid_map (),
119
+ m_log_event_processing (false )
318
120
{
319
- public:
320
- EventReset ():
321
- EventBase ()
322
- {
323
- }
121
+ }
324
122
325
- EventLoopResult
326
- ProcessEvent (ThreadStateCoordinator &coordinator) override
327
- {
328
- coordinator.ResetNow ();
329
- return eventLoopResultContinue;
330
- }
123
+ void
124
+ ThreadStateCoordinator::CallAfterThreadsStop (const lldb::tid_t triggering_tid,
125
+ const ThreadIDSet &wait_for_stop_tids,
126
+ const StopThreadFunction &request_thread_stop_function,
127
+ const ThreadIDFunction &call_after_function,
128
+ const ErrorFunction &error_function)
129
+ {
130
+ std::lock_guard<std::mutex> lock (m_event_mutex);
331
131
332
- std::string
333
- GetDescription () override
132
+ if (m_log_event_processing)
334
133
{
335
- return " EventReset" ;
134
+ Log (" ThreadStateCoordinator::%s about to process event: (triggering_tid: %" PRIu64 " , wait_for_stop_tids.size(): %zd)" ,
135
+ __FUNCTION__, triggering_tid, wait_for_stop_tids.size ());
336
136
}
337
- };
338
137
339
- // ===----------------------------------------------------------------------===//
138
+ DoCallAfterThreadsStop (PendingNotificationUP (new PendingNotification (
139
+ triggering_tid, wait_for_stop_tids, request_thread_stop_function,
140
+ call_after_function, error_function)));
340
141
341
- class ThreadStateCoordinator ::EventThreadStopped : public ThreadStateCoordinator::EventBase
342
- {
343
- public:
344
- EventThreadStopped (lldb::tid_t tid,
345
- bool initiated_by_llgs,
346
- const ErrorFunction &error_function):
347
- EventBase (),
348
- m_tid (tid),
349
- m_initiated_by_llgs (initiated_by_llgs),
350
- m_error_function (error_function)
142
+ if (m_log_event_processing)
351
143
{
144
+ Log (" ThreadStateCoordinator::%s event processing done" , __FUNCTION__);
352
145
}
146
+ }
353
147
354
- EventLoopResult
355
- ProcessEvent (ThreadStateCoordinator &coordinator) override
356
- {
357
- coordinator.ThreadDidStop (m_tid, m_initiated_by_llgs, m_error_function);
358
- return eventLoopResultContinue;
359
- }
148
+ void
149
+ ThreadStateCoordinator::CallAfterRunningThreadsStop (const lldb::tid_t triggering_tid,
150
+ const StopThreadFunction &request_thread_stop_function,
151
+ const ThreadIDFunction &call_after_function,
152
+ const ErrorFunction &error_function)
153
+ {
154
+ std::lock_guard<std::mutex> lock (m_event_mutex);
360
155
361
- std::string
362
- GetDescription () override
156
+ if (m_log_event_processing)
363
157
{
364
- std::ostringstream description;
365
- description << " EventThreadStopped (tid=" << m_tid << " )" ;
366
- return description.str ();
158
+ Log (" ThreadStateCoordinator::%s about to process event: (triggering_tid: %" PRIu64 " )" ,
159
+ __FUNCTION__, triggering_tid);
367
160
}
368
161
369
- private:
370
-
371
- const lldb::tid_t m_tid;
372
- const bool m_initiated_by_llgs;
373
- ErrorFunction m_error_function;
374
- };
375
-
376
- // ===----------------------------------------------------------------------===//
162
+ DoCallAfterThreadsStop (PendingNotificationUP (new PendingNotification (
163
+ triggering_tid,
164
+ request_thread_stop_function,
165
+ call_after_function,
166
+ error_function)));
377
167
378
- class ThreadStateCoordinator ::EventThreadCreate : public ThreadStateCoordinator::EventBase
379
- {
380
- public:
381
- EventThreadCreate (lldb::tid_t tid,
382
- bool is_stopped,
383
- const ErrorFunction &error_function):
384
- EventBase (),
385
- m_tid (tid),
386
- m_is_stopped (is_stopped),
387
- m_error_function (error_function)
168
+ if (m_log_event_processing)
388
169
{
170
+ Log (" ThreadStateCoordinator::%s event processing done" , __FUNCTION__);
389
171
}
172
+ }
390
173
391
- EventLoopResult
392
- ProcessEvent (ThreadStateCoordinator &coordinator) override
393
- {
394
- coordinator.ThreadWasCreated (m_tid, m_is_stopped, m_error_function);
395
- return eventLoopResultContinue;
396
- }
174
+ void
175
+ ThreadStateCoordinator::CallAfterRunningThreadsStopWithSkipTIDs (lldb::tid_t triggering_tid,
176
+ const ThreadIDSet &skip_stop_request_tids,
177
+ const StopThreadFunction &request_thread_stop_function,
178
+ const ThreadIDFunction &call_after_function,
179
+ const ErrorFunction &error_function)
180
+ {
181
+ std::lock_guard<std::mutex> lock (m_event_mutex);
397
182
398
- std::string
399
- GetDescription () override
183
+ if (m_log_event_processing)
400
184
{
401
- std::ostringstream description;
402
- description << " EventThreadCreate (tid=" << m_tid << " , " << (m_is_stopped ? " stopped" : " running" ) << " )" ;
403
- return description.str ();
185
+ Log (" ThreadStateCoordinator::%s about to process event: (triggering_tid: %" PRIu64 " , skip_stop_request_tids.size(): %zd)" ,
186
+ __FUNCTION__, triggering_tid, skip_stop_request_tids.size ());
404
187
}
405
188
406
- private:
407
-
408
- const lldb::tid_t m_tid;
409
- const bool m_is_stopped;
410
- ErrorFunction m_error_function;
411
- };
412
-
413
- // ===----------------------------------------------------------------------===//
414
-
415
- class ThreadStateCoordinator ::EventThreadDeath : public ThreadStateCoordinator::EventBase
416
- {
417
- public:
418
- EventThreadDeath (lldb::tid_t tid,
419
- const ErrorFunction &error_function):
420
- EventBase (),
421
- m_tid (tid),
422
- m_error_function (error_function)
423
- {
424
- }
189
+ DoCallAfterThreadsStop (PendingNotificationUP (new PendingNotification (
190
+ triggering_tid,
191
+ request_thread_stop_function,
192
+ call_after_function,
193
+ skip_stop_request_tids,
194
+ error_function)));
425
195
426
- EventLoopResult
427
- ProcessEvent (ThreadStateCoordinator &coordinator) override
196
+ if (m_log_event_processing)
428
197
{
429
- coordinator.ThreadDidDie (m_tid, m_error_function);
430
- return eventLoopResultContinue;
198
+ Log (" ThreadStateCoordinator::%s event processing done" , __FUNCTION__);
431
199
}
200
+ }
432
201
433
- std::string
434
- GetDescription () override
202
+ void
203
+ ThreadStateCoordinator::SignalIfRequirementsSatisfied ()
204
+ {
205
+ if (m_pending_notification_up && m_pending_notification_up->wait_for_stop_tids .empty ())
435
206
{
436
- std::ostringstream description;
437
- description << " EventThreadDeath (tid=" << m_tid << " )" ;
438
- return description.str ();
207
+ m_pending_notification_up->call_after_function (m_pending_notification_up->triggering_tid );
208
+ m_pending_notification_up.reset ();
439
209
}
210
+ }
440
211
441
- private:
442
-
443
- const lldb::tid_t m_tid;
444
- ErrorFunction m_error_function;
445
- };
446
-
447
- // ===----------------------------------------------------------------------===//
448
-
449
- class ThreadStateCoordinator ::EventRequestResume : public ThreadStateCoordinator::EventBase
212
+ bool
213
+ ThreadStateCoordinator::RequestStopOnAllSpecifiedThreads ()
450
214
{
451
- public:
452
- EventRequestResume (lldb::tid_t tid,
453
- const ResumeThreadFunction &request_thread_resume_function,
454
- const ErrorFunction &error_function,
455
- bool error_when_already_running):
456
- EventBase (),
457
- m_tid (tid),
458
- m_request_thread_resume_function (request_thread_resume_function),
459
- m_error_function (error_function),
460
- m_error_when_already_running (error_when_already_running)
461
- {
462
- }
215
+ // Request a stop for all the thread stops that need to be stopped
216
+ // and are not already known to be stopped. Keep a list of all the
217
+ // threads from which we still need to hear a stop reply.
463
218
464
- EventLoopResult
465
- ProcessEvent (ThreadStateCoordinator &coordinator) override
219
+ ThreadIDSet sent_tids;
220
+ for ( auto tid : m_pending_notification_up-> wait_for_stop_tids )
466
221
{
467
- // Ensure we know about the thread.
468
- auto find_it = coordinator.m_tid_map .find (m_tid);
469
- if (find_it == coordinator.m_tid_map .end ())
222
+ // Validate we know about all tids for which we must first receive a stop before
223
+ // triggering the deferred stop notification.
224
+ auto find_it = m_tid_map.find (tid);
225
+ if (find_it == m_tid_map.end ())
470
226
{
471
- // We don't know about this thread. This is an error condition.
227
+ // This is an error. We shouldn't be asking for waiting pids that aren't known.
228
+ // NOTE: we may be stripping out the specification of wait tids and handle this
229
+ // automatically, in which case this state can never occur.
472
230
std::ostringstream error_message;
473
- error_message << " error: tid " << m_tid << " asked to resume but tid is unknown" ;
474
- m_error_function (error_message.str ());
475
- return eventLoopResultContinue;
476
- }
477
- auto & context = find_it->second ;
478
- // Tell the thread to resume if we don't already think it is running.
479
- const bool is_stopped = context.m_state == ThreadState::Stopped;
480
- if (!is_stopped)
481
- {
482
- // It's not an error, just a log, if the m_already_running_no_error flag is set.
483
- // This covers cases where, for instance, we're just trying to resume all threads
484
- // from the user side.
485
- if (!m_error_when_already_running)
486
- {
487
- coordinator.Log (" EventRequestResume::%s tid %" PRIu64 " optional resume skipped since it is already running" ,
488
- __FUNCTION__,
489
- m_tid);
490
- }
491
- else
492
- {
493
- // Skip the resume call - we have tracked it to be running. And we unconditionally
494
- // expected to resume this thread. Flag this as an error.
495
- std::ostringstream error_message;
496
- error_message << " error: tid " << m_tid << " asked to resume but we think it is already running" ;
497
- m_error_function (error_message.str ());
498
- }
499
-
500
- // Error or not, we're done.
501
- return eventLoopResultContinue;
502
- }
231
+ error_message << " error: deferred notification for tid " << m_pending_notification_up->triggering_tid << " specified an unknown/untracked pending stop tid " << m_pending_notification_up->triggering_tid ;
232
+ m_pending_notification_up->error_function (error_message.str ());
503
233
504
- // Before we do the resume below, first check if we have a pending
505
- // stop notification this is currently or was previously waiting for
506
- // this thread to stop. This is potentially a buggy situation since
507
- // we're ostensibly waiting for threads to stop before we send out the
508
- // pending notification, and here we are resuming one before we send
509
- // out the pending stop notification.
510
- const EventCallAfterThreadsStop *const pending_stop_notification = coordinator.GetPendingThreadStopNotification ();
511
- if (pending_stop_notification)
512
- {
513
- if (pending_stop_notification->GetRemainingWaitTIDs ().count (m_tid) > 0 )
514
- {
515
- coordinator.Log (" EventRequestResume::%s about to resume tid %" PRIu64 " per explicit request but we have a pending stop notification (tid %" PRIu64 " ) that is actively waiting for this thread to stop. Valid sequence of events?" , __FUNCTION__, m_tid, pending_stop_notification->GetTriggeringTID ());
516
- }
517
- else if (pending_stop_notification->GetInitialWaitTIDs ().count (m_tid) > 0 )
518
- {
519
- coordinator.Log (" EventRequestResume::%s about to resume tid %" PRIu64 " per explicit request but we have a pending stop notification (tid %" PRIu64 " ) that hasn't fired yet and this is one of the threads we had been waiting on (and already marked satisfied for this tid). Valid sequence of events?" , __FUNCTION__, m_tid, pending_stop_notification->GetTriggeringTID ());
520
- for (auto tid : pending_stop_notification->GetRemainingWaitTIDs ())
521
- {
522
- coordinator.Log (" EventRequestResume::%s tid %" PRIu64 " deferred stop notification still waiting on tid %" PRIu64,
523
- __FUNCTION__,
524
- pending_stop_notification->GetTriggeringTID (),
525
- tid);
526
- }
527
- }
234
+ // Bail out here.
235
+ return false ;
528
236
}
529
237
530
- // Request a resume. We expect this to be synchronous and the system
531
- // to reflect it is running after this completes.
532
- const auto error = m_request_thread_resume_function (m_tid, false );
533
- if (error.Success ())
534
- {
535
- // Now mark it is running.
536
- context.m_state = ThreadState::Running;
537
- context.m_request_resume_function = m_request_thread_resume_function;
538
- }
539
- else
238
+ // If the pending stop thread is currently running, we need to send it a stop request.
239
+ auto & context = find_it->second ;
240
+ if (context.m_state == ThreadState::Running)
540
241
{
541
- coordinator. Log ( " EventRequestResume::%s failed to resume thread tid % " PRIu64 " : %s " ,
542
- __FUNCTION__, m_tid, error. AsCString () );
242
+ RequestThreadStop ( tid, context);
243
+ sent_tids. insert (tid );
543
244
}
544
-
545
- return eventLoopResultContinue;
546
245
}
246
+ // We only need to wait for the sent_tids - so swap our wait set
247
+ // to the sent tids. The rest are already stopped and we won't
248
+ // be receiving stop notifications for them.
249
+ m_pending_notification_up->wait_for_stop_tids .swap (sent_tids);
547
250
548
- std::string
549
- GetDescription () override
550
- {
551
- std::ostringstream description;
552
- description << " EventRequestResume (tid=" << m_tid << " )" ;
553
- return description.str ();
554
- }
555
-
556
- private:
557
-
558
- const lldb::tid_t m_tid;
559
- ResumeThreadFunction m_request_thread_resume_function;
560
- ErrorFunction m_error_function;
561
- const bool m_error_when_already_running;
562
- };
563
-
564
- // ===----------------------------------------------------------------------===//
565
-
566
- ThreadStateCoordinator::ThreadStateCoordinator (const LogFunction &log_function) :
567
- m_log_function (log_function),
568
- m_tid_map (),
569
- m_log_event_processing (false )
570
- {
251
+ // Succeeded, keep running.
252
+ return true ;
571
253
}
572
254
573
255
void
574
- ThreadStateCoordinator::SetPendingNotification ( const EventBaseSP &event_sp )
256
+ ThreadStateCoordinator::RequestStopOnAllRunningThreads ( )
575
257
{
576
- assert (event_sp && " null event_sp " );
577
- if (!event_sp)
578
- return ;
258
+ // Request a stop for all the thread stops that need to be stopped
259
+ // and are not already known to be stopped. Keep a list of all the
260
+ // threads from which we still need to hear a stop reply.
579
261
580
- const EventCallAfterThreadsStop *new_call_after_event = static_cast <EventCallAfterThreadsStop*> (event_sp.get ());
581
-
582
- EventCallAfterThreadsStop *const prev_call_after_event = GetPendingThreadStopNotification ();
583
- if (prev_call_after_event)
262
+ ThreadIDSet sent_tids;
263
+ for (auto it = m_tid_map.begin (); it != m_tid_map.end (); ++it)
584
264
{
585
- // Yikes - we've already got a pending signal notification in progress.
586
- // Log this info. We lose the pending notification here.
587
- Log (" ThreadStateCoordinator::%s dropping existing pending signal notification for tid %" PRIu64 " , to be replaced with signal for tid %" PRIu64,
588
- __FUNCTION__,
589
- prev_call_after_event->GetTriggeringTID (),
590
- new_call_after_event->GetTriggeringTID ());
591
- }
265
+ // We only care about threads not stopped.
266
+ const bool running = it->second .m_state == ThreadState::Running;
267
+ if (running)
268
+ {
269
+ const lldb::tid_t tid = it->first ;
592
270
593
- m_pending_notification_sp = event_sp;
594
- }
271
+ // Request this thread stop if the tid stop request is not explicitly ignored.
272
+ const bool skip_stop_request = m_pending_notification_up->skip_stop_request_tids .count (tid) > 0 ;
273
+ if (!skip_stop_request)
274
+ RequestThreadStop (tid, it->second );
595
275
596
- void
597
- ThreadStateCoordinator::CallAfterThreadsStop (const lldb::tid_t triggering_tid,
598
- const ThreadIDSet &wait_for_stop_tids,
599
- const StopThreadFunction &request_thread_stop_function,
600
- const ThreadIDFunction &call_after_function,
601
- const ErrorFunction &error_function)
602
- {
603
- ProcessEvent (EventBaseSP (new EventCallAfterThreadsStop (triggering_tid,
604
- wait_for_stop_tids,
605
- request_thread_stop_function,
606
- call_after_function,
607
- error_function)));
608
- }
276
+ // Even if we skipped sending the stop request for other reasons (like stepping),
277
+ // we still need to wait for that stepping thread to notify completion/stop.
278
+ sent_tids.insert (tid);
279
+ }
280
+ }
609
281
610
- void
611
- ThreadStateCoordinator::CallAfterRunningThreadsStop (const lldb::tid_t triggering_tid,
612
- const StopThreadFunction &request_thread_stop_function,
613
- const ThreadIDFunction &call_after_function,
614
- const ErrorFunction &error_function)
615
- {
616
- ProcessEvent (EventBaseSP (new EventCallAfterThreadsStop (triggering_tid,
617
- request_thread_stop_function,
618
- call_after_function,
619
- error_function)));
282
+ // Set the wait list to the set of tids for which we requested stops.
283
+ m_pending_notification_up->wait_for_stop_tids .swap (sent_tids);
620
284
}
621
285
622
286
void
623
- ThreadStateCoordinator::CallAfterRunningThreadsStopWithSkipTIDs (lldb::tid_t triggering_tid,
624
- const ThreadIDSet &skip_stop_request_tids,
625
- const StopThreadFunction &request_thread_stop_function,
626
- const ThreadIDFunction &call_after_function,
627
- const ErrorFunction &error_function)
287
+ ThreadStateCoordinator::RequestThreadStop (lldb::tid_t tid, ThreadContext& context)
628
288
{
629
- ProcessEvent (EventBaseSP (new EventCallAfterThreadsStop (triggering_tid,
630
- request_thread_stop_function,
631
- call_after_function,
632
- skip_stop_request_tids,
633
- error_function)));
289
+ const auto error = m_pending_notification_up->request_thread_stop_function (tid);
290
+ if (error.Success ())
291
+ context.m_stop_requested = true ;
292
+ else
293
+ {
294
+ Log (" ThreadStateCoordinator::%s failed to request thread stop tid %" PRIu64 " : %s" ,
295
+ __FUNCTION__, tid, error.AsCString ());
296
+ }
634
297
}
635
298
636
299
637
300
void
638
- ThreadStateCoordinator::ThreadDidStop (lldb::tid_t tid, bool initiated_by_llgs, ErrorFunction &error_function)
301
+ ThreadStateCoordinator::ThreadDidStop (lldb::tid_t tid, bool initiated_by_llgs, const ErrorFunction &error_function)
639
302
{
640
303
// Ensure we know about the thread.
641
304
auto find_it = m_tid_map.find (tid);
@@ -655,15 +318,10 @@ ThreadStateCoordinator::ThreadDidStop (lldb::tid_t tid, bool initiated_by_llgs,
655
318
context.m_stop_requested = false ;
656
319
657
320
// If we have a pending notification, remove this from the set.
658
- EventCallAfterThreadsStop *const call_after_event = GetPendingThreadStopNotification ();
659
- if (call_after_event)
321
+ if (m_pending_notification_up)
660
322
{
661
- const bool pending_stops_remain = call_after_event->RemoveThreadStopRequirementAndMaybeSignal (tid);
662
- if (!pending_stops_remain)
663
- {
664
- // Clear the pending notification now.
665
- m_pending_notification_sp.reset ();
666
- }
323
+ m_pending_notification_up->wait_for_stop_tids .erase (tid);
324
+ SignalIfRequirementsSatisfied ();
667
325
}
668
326
669
327
if (initiated_by_llgs && context.m_request_resume_function && !stop_was_requested)
@@ -685,7 +343,49 @@ ThreadStateCoordinator::ThreadDidStop (lldb::tid_t tid, bool initiated_by_llgs,
685
343
}
686
344
687
345
void
688
- ThreadStateCoordinator::ThreadWasCreated (lldb::tid_t tid, bool is_stopped, ErrorFunction &error_function)
346
+ ThreadStateCoordinator::DoCallAfterThreadsStop (PendingNotificationUP &¬ification_up)
347
+ {
348
+ // Validate we know about the deferred trigger thread.
349
+ if (!IsKnownThread (notification_up->triggering_tid ))
350
+ {
351
+ // We don't know about this thread. This is an error condition.
352
+ std::ostringstream error_message;
353
+ error_message << " error: deferred notification tid " << notification_up->triggering_tid << " is unknown" ;
354
+ notification_up->error_function (error_message.str ());
355
+
356
+ // We bail out here.
357
+ return ;
358
+ }
359
+
360
+ if (m_pending_notification_up)
361
+ {
362
+ // Yikes - we've already got a pending signal notification in progress.
363
+ // Log this info. We lose the pending notification here.
364
+ Log (" ThreadStateCoordinator::%s dropping existing pending signal notification for tid %" PRIu64 " , to be replaced with signal for tid %" PRIu64,
365
+ __FUNCTION__,
366
+ m_pending_notification_up->triggering_tid ,
367
+ notification_up->triggering_tid );
368
+ }
369
+ m_pending_notification_up = std::move (notification_up);
370
+
371
+ if (m_pending_notification_up->request_stop_on_all_unstopped_threads )
372
+ RequestStopOnAllRunningThreads ();
373
+ else
374
+ {
375
+ if (!RequestStopOnAllSpecifiedThreads ())
376
+ return ;
377
+ }
378
+
379
+ if (m_pending_notification_up->wait_for_stop_tids .empty ())
380
+ {
381
+ // We're not waiting for any threads. Fire off the deferred signal delivery event.
382
+ m_pending_notification_up->call_after_function (m_pending_notification_up->triggering_tid );
383
+ m_pending_notification_up.reset ();
384
+ }
385
+ }
386
+
387
+ void
388
+ ThreadStateCoordinator::ThreadWasCreated (lldb::tid_t tid, bool is_stopped, const ErrorFunction &error_function)
689
389
{
690
390
// Ensure we don't already know about the thread.
691
391
auto find_it = m_tid_map.find (tid);
@@ -703,17 +403,17 @@ ThreadStateCoordinator::ThreadWasCreated (lldb::tid_t tid, bool is_stopped, Erro
703
403
ctx.m_state = (is_stopped) ? ThreadState::Stopped : ThreadState::Running;
704
404
m_tid_map[tid] = std::move (ctx);
705
405
706
- EventCallAfterThreadsStop *const call_after_event = GetPendingThreadStopNotification ();
707
- if (call_after_event && !is_stopped)
406
+ if (m_pending_notification_up && !is_stopped)
708
407
{
709
- // Tell the pending notification that we need to wait
710
- // for this new thread to stop.
711
- call_after_event->AddThreadStopRequirement (tid);
408
+ // We will need to wait for this new thread to stop as well before firing the
409
+ // notification.
410
+ m_pending_notification_up->wait_for_stop_tids .insert (tid);
411
+ m_pending_notification_up->request_thread_stop_function (tid);
712
412
}
713
413
}
714
414
715
415
void
716
- ThreadStateCoordinator::ThreadDidDie (lldb::tid_t tid, ErrorFunction &error_function)
416
+ ThreadStateCoordinator::ThreadDidDie (lldb::tid_t tid, const ErrorFunction &error_function)
717
417
{
718
418
// Ensure we know about the thread.
719
419
auto find_it = m_tid_map.find (tid);
@@ -732,31 +432,13 @@ ThreadStateCoordinator::ThreadDidDie (lldb::tid_t tid, ErrorFunction &error_func
732
432
m_tid_map.erase (find_it);
733
433
734
434
// If we have a pending notification, remove this from the set.
735
- EventCallAfterThreadsStop *const call_after_event = GetPendingThreadStopNotification ();
736
- if (call_after_event)
435
+ if (m_pending_notification_up)
737
436
{
738
- const bool pending_stops_remain = call_after_event->RemoveThreadStopRequirementAndMaybeSignal (tid);
739
- if (!pending_stops_remain)
740
- {
741
- // Clear the pending notification now.
742
- m_pending_notification_sp.reset ();
743
- }
437
+ m_pending_notification_up->wait_for_stop_tids .erase (tid);
438
+ SignalIfRequirementsSatisfied ();
744
439
}
745
440
}
746
441
747
- void
748
- ThreadStateCoordinator::ResetNow ()
749
- {
750
- // Clear the pending notification if there was one.
751
- m_pending_notification_sp.reset ();
752
-
753
- // Clear the stop map - we no longer know anything about any thread state.
754
- // The caller is expected to reset thread states for all threads, and we
755
- // will assume anything we haven't heard about is running and requires a
756
- // stop.
757
- m_tid_map.clear ();
758
- }
759
-
760
442
void
761
443
ThreadStateCoordinator::Log (const char *format, ...)
762
444
{
@@ -773,77 +455,134 @@ ThreadStateCoordinator::NotifyThreadStop (lldb::tid_t tid,
773
455
bool initiated_by_llgs,
774
456
const ErrorFunction &error_function)
775
457
{
776
- ProcessEvent (EventBaseSP (new EventThreadStopped (tid, initiated_by_llgs, error_function)));
458
+ std::lock_guard<std::mutex> lock (m_event_mutex);
459
+
460
+ if (m_log_event_processing)
461
+ {
462
+ Log (" ThreadStateCoordinator::%s about to process event: (tid: %" PRIu64 " , %sinitiated by llgs)" ,
463
+ __FUNCTION__, tid, initiated_by_llgs?" " :" not " );
464
+ }
465
+
466
+ ThreadDidStop (tid, initiated_by_llgs, error_function);
467
+
468
+ if (m_log_event_processing)
469
+ {
470
+ Log (" ThreadStateCoordinator::%s event processing done" , __FUNCTION__);
471
+ }
777
472
}
778
473
779
474
void
780
475
ThreadStateCoordinator::RequestThreadResume (lldb::tid_t tid,
781
476
const ResumeThreadFunction &request_thread_resume_function,
782
477
const ErrorFunction &error_function)
783
478
{
784
- ProcessEvent (EventBaseSP (new EventRequestResume (tid, request_thread_resume_function, error_function, true )));
479
+ std::lock_guard<std::mutex> lock (m_event_mutex);
480
+
481
+ if (m_log_event_processing)
482
+ {
483
+ Log (" ThreadStateCoordinator::%s about to process event: (tid: %" PRIu64 " )" ,
484
+ __FUNCTION__, tid);
485
+ }
486
+
487
+ DoResume (tid, request_thread_resume_function, error_function, true );
488
+
489
+ if (m_log_event_processing)
490
+ {
491
+ Log (" ThreadStateCoordinator::%s event processing done" , __FUNCTION__);
492
+ }
785
493
}
786
494
787
495
void
788
496
ThreadStateCoordinator::RequestThreadResumeAsNeeded (lldb::tid_t tid,
789
497
const ResumeThreadFunction &request_thread_resume_function,
790
498
const ErrorFunction &error_function)
791
499
{
792
- ProcessEvent (EventBaseSP (new EventRequestResume (tid, request_thread_resume_function, error_function, false )));
500
+ std::lock_guard<std::mutex> lock (m_event_mutex);
501
+
502
+ if (m_log_event_processing)
503
+ {
504
+ Log (" ThreadStateCoordinator::%s about to process event: (tid: %" PRIu64 " )" ,
505
+ __FUNCTION__, tid);
506
+ }
507
+
508
+ DoResume (tid, request_thread_resume_function, error_function, false );
509
+
510
+ if (m_log_event_processing)
511
+ {
512
+ Log (" ThreadStateCoordinator::%s event processing done" , __FUNCTION__);
513
+ }
793
514
}
794
515
795
516
void
796
517
ThreadStateCoordinator::NotifyThreadCreate (lldb::tid_t tid,
797
518
bool is_stopped,
798
519
const ErrorFunction &error_function)
799
520
{
800
- ProcessEvent (EventBaseSP (new EventThreadCreate (tid, is_stopped, error_function)));
521
+ std::lock_guard<std::mutex> lock (m_event_mutex);
522
+
523
+ if (m_log_event_processing)
524
+ {
525
+ Log (" ThreadStateCoordinator::%s about to process event: (tid: %" PRIu64 " , is %sstopped)" ,
526
+ __FUNCTION__, tid, is_stopped?" " :" not " );
527
+ }
528
+
529
+ ThreadWasCreated (tid, is_stopped, error_function);
530
+
531
+ if (m_log_event_processing)
532
+ {
533
+ Log (" ThreadStateCoordinator::%s event processing done" , __FUNCTION__);
534
+ }
801
535
}
802
536
803
537
void
804
538
ThreadStateCoordinator::NotifyThreadDeath (lldb::tid_t tid,
805
539
const ErrorFunction &error_function)
806
540
{
807
- ProcessEvent (EventBaseSP (new EventThreadDeath (tid, error_function)));
808
- }
541
+ std::lock_guard<std::mutex> lock (m_event_mutex);
809
542
810
- void
811
- ThreadStateCoordinator::ResetForExec ()
812
- {
813
- ProcessEvent (EventBaseSP (new EventReset ()));
543
+ if (m_log_event_processing)
544
+ {
545
+ Log (" ThreadStateCoordinator::%s about to process event: (tid: %" PRIu64 " )" , __FUNCTION__, tid);
546
+ }
547
+
548
+ ThreadDidDie (tid, error_function);
549
+
550
+ if (m_log_event_processing)
551
+ {
552
+ Log (" ThreadStateCoordinator::%s event processing done" , __FUNCTION__);
553
+ }
814
554
}
815
555
816
556
void
817
- ThreadStateCoordinator::ProcessEvent ( const EventBaseSP &event_sp )
557
+ ThreadStateCoordinator::ResetForExec ( )
818
558
{
819
559
std::lock_guard<std::mutex> lock (m_event_mutex);
820
560
821
561
if (m_log_event_processing)
822
562
{
823
- Log (" ThreadStateCoordinator::%s about to process event: %s " , __FUNCTION__, event_sp-> GetDescription (). c_str () );
563
+ Log (" ThreadStateCoordinator::%s about to process event" , __FUNCTION__);
824
564
}
825
565
826
- // Process the event.
827
- event_sp->ProcessEvent (*this );
566
+ // Clear the pending notification if there was one.
567
+ m_pending_notification_up.reset ();
568
+
569
+ // Clear the stop map - we no longer know anything about any thread state.
570
+ // The caller is expected to reset thread states for all threads, and we
571
+ // will assume anything we haven't heard about is running and requires a
572
+ // stop.
573
+ m_tid_map.clear ();
828
574
829
575
if (m_log_event_processing)
830
576
{
831
577
Log (" ThreadStateCoordinator::%s event processing done" , __FUNCTION__);
832
578
}
833
579
}
834
-
835
580
void
836
581
ThreadStateCoordinator::LogEnableEventProcessing (bool enabled)
837
582
{
838
583
m_log_event_processing = enabled;
839
584
}
840
585
841
- ThreadStateCoordinator::EventCallAfterThreadsStop *
842
- ThreadStateCoordinator::GetPendingThreadStopNotification ()
843
- {
844
- return static_cast <EventCallAfterThreadsStop*> (m_pending_notification_sp.get ());
845
- }
846
-
847
586
bool
848
587
ThreadStateCoordinator::IsKnownThread (lldb::tid_t tid) const
849
588
{
0 commit comments