Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Target/StopInfo.cpp
39587 views
1
//===-- StopInfo.cpp ------------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include <string>
10
11
#include "lldb/Breakpoint/Breakpoint.h"
12
#include "lldb/Breakpoint/BreakpointLocation.h"
13
#include "lldb/Breakpoint/StoppointCallbackContext.h"
14
#include "lldb/Breakpoint/Watchpoint.h"
15
#include "lldb/Breakpoint/WatchpointResource.h"
16
#include "lldb/Core/Debugger.h"
17
#include "lldb/Core/ValueObject.h"
18
#include "lldb/Expression/UserExpression.h"
19
#include "lldb/Target/Process.h"
20
#include "lldb/Target/StopInfo.h"
21
#include "lldb/Target/Target.h"
22
#include "lldb/Target/Thread.h"
23
#include "lldb/Target/ThreadPlan.h"
24
#include "lldb/Target/ThreadPlanStepInstruction.h"
25
#include "lldb/Target/UnixSignals.h"
26
#include "lldb/Utility/LLDBLog.h"
27
#include "lldb/Utility/Log.h"
28
#include "lldb/Utility/StreamString.h"
29
30
using namespace lldb;
31
using namespace lldb_private;
32
33
StopInfo::StopInfo(Thread &thread, uint64_t value)
34
: m_thread_wp(thread.shared_from_this()),
35
m_stop_id(thread.GetProcess()->GetStopID()),
36
m_resume_id(thread.GetProcess()->GetResumeID()), m_value(value),
37
m_description(), m_override_should_notify(eLazyBoolCalculate),
38
m_override_should_stop(eLazyBoolCalculate), m_extended_info() {}
39
40
bool StopInfo::IsValid() const {
41
ThreadSP thread_sp(m_thread_wp.lock());
42
if (thread_sp)
43
return thread_sp->GetProcess()->GetStopID() == m_stop_id;
44
return false;
45
}
46
47
void StopInfo::MakeStopInfoValid() {
48
ThreadSP thread_sp(m_thread_wp.lock());
49
if (thread_sp) {
50
m_stop_id = thread_sp->GetProcess()->GetStopID();
51
m_resume_id = thread_sp->GetProcess()->GetResumeID();
52
}
53
}
54
55
bool StopInfo::HasTargetRunSinceMe() {
56
ThreadSP thread_sp(m_thread_wp.lock());
57
58
if (thread_sp) {
59
lldb::StateType ret_type = thread_sp->GetProcess()->GetPrivateState();
60
if (ret_type == eStateRunning) {
61
return true;
62
} else if (ret_type == eStateStopped) {
63
// This is a little tricky. We want to count "run and stopped again
64
// before you could ask this question as a "TRUE" answer to
65
// HasTargetRunSinceMe. But we don't want to include any running of the
66
// target done for expressions. So we track both resumes, and resumes
67
// caused by expressions, and check if there are any resumes
68
// NOT caused
69
// by expressions.
70
71
uint32_t curr_resume_id = thread_sp->GetProcess()->GetResumeID();
72
uint32_t last_user_expression_id =
73
thread_sp->GetProcess()->GetLastUserExpressionResumeID();
74
if (curr_resume_id == m_resume_id) {
75
return false;
76
} else if (curr_resume_id > last_user_expression_id) {
77
return true;
78
}
79
}
80
}
81
return false;
82
}
83
84
// StopInfoBreakpoint
85
86
namespace lldb_private {
87
class StopInfoBreakpoint : public StopInfo {
88
public:
89
StopInfoBreakpoint(Thread &thread, break_id_t break_id)
90
: StopInfo(thread, break_id), m_should_stop(false),
91
m_should_stop_is_valid(false), m_should_perform_action(true),
92
m_address(LLDB_INVALID_ADDRESS), m_break_id(LLDB_INVALID_BREAK_ID),
93
m_was_all_internal(false), m_was_one_shot(false) {
94
StoreBPInfo();
95
}
96
97
StopInfoBreakpoint(Thread &thread, break_id_t break_id, bool should_stop)
98
: StopInfo(thread, break_id), m_should_stop(should_stop),
99
m_should_stop_is_valid(true), m_should_perform_action(true),
100
m_address(LLDB_INVALID_ADDRESS), m_break_id(LLDB_INVALID_BREAK_ID),
101
m_was_all_internal(false), m_was_one_shot(false) {
102
StoreBPInfo();
103
}
104
105
~StopInfoBreakpoint() override = default;
106
107
void StoreBPInfo() {
108
ThreadSP thread_sp(m_thread_wp.lock());
109
if (thread_sp) {
110
BreakpointSiteSP bp_site_sp(
111
thread_sp->GetProcess()->GetBreakpointSiteList().FindByID(m_value));
112
if (bp_site_sp) {
113
uint32_t num_constituents = bp_site_sp->GetNumberOfConstituents();
114
if (num_constituents == 1) {
115
BreakpointLocationSP bp_loc_sp = bp_site_sp->GetConstituentAtIndex(0);
116
if (bp_loc_sp) {
117
Breakpoint & bkpt = bp_loc_sp->GetBreakpoint();
118
m_break_id = bkpt.GetID();
119
m_was_one_shot = bkpt.IsOneShot();
120
m_was_all_internal = bkpt.IsInternal();
121
}
122
} else {
123
m_was_all_internal = true;
124
for (uint32_t i = 0; i < num_constituents; i++) {
125
if (!bp_site_sp->GetConstituentAtIndex(i)
126
->GetBreakpoint()
127
.IsInternal()) {
128
m_was_all_internal = false;
129
break;
130
}
131
}
132
}
133
m_address = bp_site_sp->GetLoadAddress();
134
}
135
}
136
}
137
138
bool IsValidForOperatingSystemThread(Thread &thread) override {
139
ProcessSP process_sp(thread.GetProcess());
140
if (process_sp) {
141
BreakpointSiteSP bp_site_sp(
142
process_sp->GetBreakpointSiteList().FindByID(m_value));
143
if (bp_site_sp)
144
return bp_site_sp->ValidForThisThread(thread);
145
}
146
return false;
147
}
148
149
StopReason GetStopReason() const override { return eStopReasonBreakpoint; }
150
151
bool ShouldStopSynchronous(Event *event_ptr) override {
152
ThreadSP thread_sp(m_thread_wp.lock());
153
if (thread_sp) {
154
if (!m_should_stop_is_valid) {
155
// Only check once if we should stop at a breakpoint
156
BreakpointSiteSP bp_site_sp(
157
thread_sp->GetProcess()->GetBreakpointSiteList().FindByID(m_value));
158
if (bp_site_sp) {
159
ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
160
StoppointCallbackContext context(event_ptr, exe_ctx, true);
161
bp_site_sp->BumpHitCounts();
162
m_should_stop = bp_site_sp->ShouldStop(&context);
163
} else {
164
Log *log = GetLog(LLDBLog::Process);
165
166
LLDB_LOGF(log,
167
"Process::%s could not find breakpoint site id: %" PRId64
168
"...",
169
__FUNCTION__, m_value);
170
171
m_should_stop = true;
172
}
173
m_should_stop_is_valid = true;
174
}
175
return m_should_stop;
176
}
177
return false;
178
}
179
180
bool DoShouldNotify(Event *event_ptr) override {
181
return !m_was_all_internal;
182
}
183
184
const char *GetDescription() override {
185
if (m_description.empty()) {
186
ThreadSP thread_sp(m_thread_wp.lock());
187
if (thread_sp) {
188
BreakpointSiteSP bp_site_sp(
189
thread_sp->GetProcess()->GetBreakpointSiteList().FindByID(m_value));
190
if (bp_site_sp) {
191
StreamString strm;
192
// If we have just hit an internal breakpoint, and it has a kind
193
// description, print that instead of the full breakpoint printing:
194
if (bp_site_sp->IsInternal()) {
195
size_t num_constituents = bp_site_sp->GetNumberOfConstituents();
196
for (size_t idx = 0; idx < num_constituents; idx++) {
197
const char *kind = bp_site_sp->GetConstituentAtIndex(idx)
198
->GetBreakpoint()
199
.GetBreakpointKind();
200
if (kind != nullptr) {
201
m_description.assign(kind);
202
return kind;
203
}
204
}
205
}
206
207
strm.Printf("breakpoint ");
208
bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief);
209
m_description = std::string(strm.GetString());
210
} else {
211
StreamString strm;
212
if (m_break_id != LLDB_INVALID_BREAK_ID) {
213
BreakpointSP break_sp =
214
thread_sp->GetProcess()->GetTarget().GetBreakpointByID(
215
m_break_id);
216
if (break_sp) {
217
if (break_sp->IsInternal()) {
218
const char *kind = break_sp->GetBreakpointKind();
219
if (kind)
220
strm.Printf("internal %s breakpoint(%d).", kind, m_break_id);
221
else
222
strm.Printf("internal breakpoint(%d).", m_break_id);
223
} else {
224
strm.Printf("breakpoint %d.", m_break_id);
225
}
226
} else {
227
if (m_was_one_shot)
228
strm.Printf("one-shot breakpoint %d", m_break_id);
229
else
230
strm.Printf("breakpoint %d which has been deleted.",
231
m_break_id);
232
}
233
} else if (m_address == LLDB_INVALID_ADDRESS)
234
strm.Printf("breakpoint site %" PRIi64
235
" which has been deleted - unknown address",
236
m_value);
237
else
238
strm.Printf("breakpoint site %" PRIi64
239
" which has been deleted - was at 0x%" PRIx64,
240
m_value, m_address);
241
242
m_description = std::string(strm.GetString());
243
}
244
}
245
}
246
return m_description.c_str();
247
}
248
249
protected:
250
bool ShouldStop(Event *event_ptr) override {
251
// This just reports the work done by PerformAction or the synchronous
252
// stop. It should only ever get called after they have had a chance to
253
// run.
254
assert(m_should_stop_is_valid);
255
return m_should_stop;
256
}
257
258
void PerformAction(Event *event_ptr) override {
259
if (!m_should_perform_action)
260
return;
261
m_should_perform_action = false;
262
bool all_stopping_locs_internal = true;
263
264
ThreadSP thread_sp(m_thread_wp.lock());
265
266
if (thread_sp) {
267
Log *log = GetLog(LLDBLog::Breakpoints | LLDBLog::Step);
268
269
if (!thread_sp->IsValid()) {
270
// This shouldn't ever happen, but just in case, don't do more harm.
271
if (log) {
272
LLDB_LOGF(log, "PerformAction got called with an invalid thread.");
273
}
274
m_should_stop = true;
275
m_should_stop_is_valid = true;
276
return;
277
}
278
279
BreakpointSiteSP bp_site_sp(
280
thread_sp->GetProcess()->GetBreakpointSiteList().FindByID(m_value));
281
std::unordered_set<break_id_t> precondition_breakpoints;
282
// Breakpoints that fail their condition check are not considered to
283
// have been hit. If the only locations at this site have failed their
284
// conditions, we should change the stop-info to none. Otherwise, if we
285
// hit another breakpoint on a different thread which does stop, users
286
// will see a breakpont hit with a failed condition, which is wrong.
287
// Use this variable to tell us if that is true.
288
bool actually_hit_any_locations = false;
289
if (bp_site_sp) {
290
// Let's copy the constituents list out of the site and store them in a
291
// local list. That way if one of the breakpoint actions changes the
292
// site, then we won't be operating on a bad list.
293
BreakpointLocationCollection site_locations;
294
size_t num_constituents =
295
bp_site_sp->CopyConstituentsList(site_locations);
296
297
if (num_constituents == 0) {
298
m_should_stop = true;
299
actually_hit_any_locations = true; // We're going to stop, don't
300
// change the stop info.
301
} else {
302
// We go through each location, and test first its precondition -
303
// this overrides everything. Note, we only do this once per
304
// breakpoint - not once per location... Then check the condition.
305
// If the condition says to stop, then we run the callback for that
306
// location. If that callback says to stop as well, then we set
307
// m_should_stop to true; we are going to stop. But we still want to
308
// give all the breakpoints whose conditions say we are going to stop
309
// a chance to run their callbacks. Of course if any callback
310
// restarts the target by putting "continue" in the callback, then
311
// we're going to restart, without running the rest of the callbacks.
312
// And in this case we will end up not stopping even if another
313
// location said we should stop. But that's better than not running
314
// all the callbacks.
315
316
// There's one other complication here. We may have run an async
317
// breakpoint callback that said we should stop. We only want to
318
// override that if another breakpoint action says we shouldn't
319
// stop. If nobody else has an opinion, then we should stop if the
320
// async callback says we should. An example of this is the async
321
// shared library load notification breakpoint and the setting
322
// stop-on-sharedlibrary-events.
323
// We'll keep the async value in async_should_stop, and track whether
324
// anyone said we should NOT stop in actually_said_continue.
325
bool async_should_stop = false;
326
if (m_should_stop_is_valid)
327
async_should_stop = m_should_stop;
328
bool actually_said_continue = false;
329
330
m_should_stop = false;
331
332
// We don't select threads as we go through them testing breakpoint
333
// conditions and running commands. So we need to set the thread for
334
// expression evaluation here:
335
ThreadList::ExpressionExecutionThreadPusher thread_pusher(thread_sp);
336
337
ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
338
Process *process = exe_ctx.GetProcessPtr();
339
if (process->GetModIDRef().IsRunningExpression()) {
340
// If we are in the middle of evaluating an expression, don't run
341
// asynchronous breakpoint commands or expressions. That could
342
// lead to infinite recursion if the command or condition re-calls
343
// the function with this breakpoint.
344
// TODO: We can keep a list of the breakpoints we've seen while
345
// running expressions in the nested
346
// PerformAction calls that can arise when the action runs a
347
// function that hits another breakpoint, and only stop running
348
// commands when we see the same breakpoint hit a second time.
349
350
m_should_stop_is_valid = true;
351
352
// It is possible that the user has a breakpoint at the same site
353
// as the completed plan had (e.g. user has a breakpoint
354
// on a module entry point, and `ThreadPlanCallFunction` ends
355
// also there). We can't find an internal breakpoint in the loop
356
// later because it was already removed on the plan completion.
357
// So check if the plan was completed, and stop if so.
358
if (thread_sp->CompletedPlanOverridesBreakpoint()) {
359
m_should_stop = true;
360
thread_sp->ResetStopInfo();
361
return;
362
}
363
364
LLDB_LOGF(log, "StopInfoBreakpoint::PerformAction - Hit a "
365
"breakpoint while running an expression,"
366
" not running commands to avoid recursion.");
367
bool ignoring_breakpoints =
368
process->GetIgnoreBreakpointsInExpressions();
369
// Internal breakpoints should be allowed to do their job, we
370
// can make sure they don't do anything that would cause recursive
371
// command execution:
372
if (!m_was_all_internal) {
373
m_should_stop = !ignoring_breakpoints;
374
LLDB_LOGF(log,
375
"StopInfoBreakpoint::PerformAction - in expression, "
376
"continuing: %s.",
377
m_should_stop ? "true" : "false");
378
Debugger::ReportWarning(
379
"hit breakpoint while running function, skipping commands "
380
"and conditions to prevent recursion",
381
process->GetTarget().GetDebugger().GetID());
382
return;
383
}
384
}
385
386
StoppointCallbackContext context(event_ptr, exe_ctx, false);
387
388
// For safety's sake let's also grab an extra reference to the
389
// breakpoint constituents of the locations we're going to examine,
390
// since the locations are going to have to get back to their
391
// breakpoints, and the locations don't keep their constituents alive.
392
// I'm just sticking the BreakpointSP's in a vector since I'm only
393
// using it to locally increment their retain counts.
394
395
std::vector<lldb::BreakpointSP> location_constituents;
396
397
for (size_t j = 0; j < num_constituents; j++) {
398
BreakpointLocationSP loc(site_locations.GetByIndex(j));
399
location_constituents.push_back(
400
loc->GetBreakpoint().shared_from_this());
401
}
402
403
for (size_t j = 0; j < num_constituents; j++) {
404
lldb::BreakpointLocationSP bp_loc_sp = site_locations.GetByIndex(j);
405
StreamString loc_desc;
406
if (log) {
407
bp_loc_sp->GetDescription(&loc_desc, eDescriptionLevelBrief);
408
}
409
// If another action disabled this breakpoint or its location, then
410
// don't run the actions.
411
if (!bp_loc_sp->IsEnabled() ||
412
!bp_loc_sp->GetBreakpoint().IsEnabled())
413
continue;
414
415
// The breakpoint site may have many locations associated with it,
416
// not all of them valid for this thread. Skip the ones that
417
// aren't:
418
if (!bp_loc_sp->ValidForThisThread(*thread_sp)) {
419
if (log) {
420
LLDB_LOGF(log,
421
"Breakpoint %s hit on thread 0x%llx but it was not "
422
"for this thread, continuing.",
423
loc_desc.GetData(),
424
static_cast<unsigned long long>(thread_sp->GetID()));
425
}
426
continue;
427
}
428
429
// First run the precondition, but since the precondition is per
430
// breakpoint, only run it once per breakpoint.
431
std::pair<std::unordered_set<break_id_t>::iterator, bool> result =
432
precondition_breakpoints.insert(
433
bp_loc_sp->GetBreakpoint().GetID());
434
if (!result.second)
435
continue;
436
437
bool precondition_result =
438
bp_loc_sp->GetBreakpoint().EvaluatePrecondition(context);
439
if (!precondition_result) {
440
actually_said_continue = true;
441
continue;
442
}
443
// Next run the condition for the breakpoint. If that says we
444
// should stop, then we'll run the callback for the breakpoint. If
445
// the callback says we shouldn't stop that will win.
446
447
if (bp_loc_sp->GetConditionText() == nullptr)
448
actually_hit_any_locations = true;
449
else {
450
Status condition_error;
451
bool condition_says_stop =
452
bp_loc_sp->ConditionSaysStop(exe_ctx, condition_error);
453
454
if (!condition_error.Success()) {
455
// If the condition fails to evaluate, we are going to stop
456
// at it, so the location was hit.
457
actually_hit_any_locations = true;
458
const char *err_str =
459
condition_error.AsCString("<unknown error>");
460
LLDB_LOGF(log, "Error evaluating condition: \"%s\"\n", err_str);
461
462
StreamString strm;
463
strm << "stopped due to an error evaluating condition of "
464
"breakpoint ";
465
bp_loc_sp->GetDescription(&strm, eDescriptionLevelBrief);
466
strm << ": \"" << bp_loc_sp->GetConditionText() << "\"\n";
467
strm << err_str;
468
469
Debugger::ReportError(
470
strm.GetString().str(),
471
exe_ctx.GetTargetRef().GetDebugger().GetID());
472
} else {
473
LLDB_LOGF(log,
474
"Condition evaluated for breakpoint %s on thread "
475
"0x%llx condition_says_stop: %i.",
476
loc_desc.GetData(),
477
static_cast<unsigned long long>(thread_sp->GetID()),
478
condition_says_stop);
479
if (condition_says_stop)
480
actually_hit_any_locations = true;
481
else {
482
// We don't want to increment the hit count of breakpoints if
483
// the condition fails. We've already bumped it by the time
484
// we get here, so undo the bump:
485
bp_loc_sp->UndoBumpHitCount();
486
actually_said_continue = true;
487
continue;
488
}
489
}
490
}
491
492
// We've done all the checks whose failure means "we consider lldb
493
// not to have hit the breakpoint". Now we're going to check for
494
// conditions that might continue after hitting. Start with the
495
// ignore count:
496
if (!bp_loc_sp->IgnoreCountShouldStop()) {
497
actually_said_continue = true;
498
continue;
499
}
500
501
// Check the auto-continue bit on the location, do this before the
502
// callback since it may change this, but that would be for the
503
// NEXT hit. Note, you might think you could check auto-continue
504
// before the condition, and not evaluate the condition if it says
505
// to continue. But failing the condition means the breakpoint was
506
// effectively NOT HIT. So these two states are different.
507
bool auto_continue_says_stop = true;
508
if (bp_loc_sp->IsAutoContinue())
509
{
510
LLDB_LOGF(log,
511
"Continuing breakpoint %s as AutoContinue was set.",
512
loc_desc.GetData());
513
// We want this stop reported, so you will know we auto-continued
514
// but only for external breakpoints:
515
if (!bp_loc_sp->GetBreakpoint().IsInternal())
516
thread_sp->SetShouldReportStop(eVoteYes);
517
auto_continue_says_stop = false;
518
}
519
520
bool callback_says_stop = true;
521
522
// FIXME: For now the callbacks have to run in async mode - the
523
// first time we restart we need
524
// to get out of there. So set it here.
525
// When we figure out how to nest breakpoint hits then this will
526
// change.
527
528
// Don't run async callbacks in PerformAction. They have already
529
// been taken into account with async_should_stop.
530
if (!bp_loc_sp->IsCallbackSynchronous()) {
531
Debugger &debugger = thread_sp->CalculateTarget()->GetDebugger();
532
bool old_async = debugger.GetAsyncExecution();
533
debugger.SetAsyncExecution(true);
534
535
callback_says_stop = bp_loc_sp->InvokeCallback(&context);
536
537
debugger.SetAsyncExecution(old_async);
538
539
if (callback_says_stop && auto_continue_says_stop)
540
m_should_stop = true;
541
else
542
actually_said_continue = true;
543
}
544
545
if (m_should_stop && !bp_loc_sp->GetBreakpoint().IsInternal())
546
all_stopping_locs_internal = false;
547
548
// If we are going to stop for this breakpoint, then remove the
549
// breakpoint.
550
if (callback_says_stop && bp_loc_sp &&
551
bp_loc_sp->GetBreakpoint().IsOneShot()) {
552
thread_sp->GetProcess()->GetTarget().RemoveBreakpointByID(
553
bp_loc_sp->GetBreakpoint().GetID());
554
}
555
// Also make sure that the callback hasn't continued the target. If
556
// it did, when we'll set m_should_start to false and get out of
557
// here.
558
if (HasTargetRunSinceMe()) {
559
m_should_stop = false;
560
actually_said_continue = true;
561
break;
562
}
563
}
564
// At this point if nobody actually told us to continue, we should
565
// give the async breakpoint callback a chance to weigh in:
566
if (!actually_said_continue && !m_should_stop) {
567
m_should_stop = async_should_stop;
568
}
569
}
570
// We've figured out what this stop wants to do, so mark it as valid so
571
// we don't compute it again.
572
m_should_stop_is_valid = true;
573
} else {
574
m_should_stop = true;
575
m_should_stop_is_valid = true;
576
actually_hit_any_locations = true;
577
Log *log_process(GetLog(LLDBLog::Process));
578
579
LLDB_LOGF(log_process,
580
"Process::%s could not find breakpoint site id: %" PRId64
581
"...",
582
__FUNCTION__, m_value);
583
}
584
585
if ((!m_should_stop || all_stopping_locs_internal) &&
586
thread_sp->CompletedPlanOverridesBreakpoint()) {
587
588
// Override should_stop decision when we have completed step plan
589
// additionally to the breakpoint
590
m_should_stop = true;
591
592
// We know we're stopping for a completed plan and we don't want to
593
// show the breakpoint stop, so compute the public stop info immediately
594
// here.
595
thread_sp->CalculatePublicStopInfo();
596
} else if (!actually_hit_any_locations) {
597
// In the end, we didn't actually have any locations that passed their
598
// "was I hit" checks. So say we aren't stopped.
599
GetThread()->ResetStopInfo();
600
LLDB_LOGF(log, "Process::%s all locations failed condition checks.",
601
__FUNCTION__);
602
}
603
604
LLDB_LOGF(log,
605
"Process::%s returning from action with m_should_stop: %d.",
606
__FUNCTION__, m_should_stop);
607
}
608
}
609
610
private:
611
bool m_should_stop;
612
bool m_should_stop_is_valid;
613
bool m_should_perform_action; // Since we are trying to preserve the "state"
614
// of the system even if we run functions
615
// etc. behind the users backs, we need to make sure we only REALLY perform
616
// the action once.
617
lldb::addr_t m_address; // We use this to capture the breakpoint site address
618
// when we create the StopInfo,
619
// in case somebody deletes it between the time the StopInfo is made and the
620
// description is asked for.
621
lldb::break_id_t m_break_id;
622
bool m_was_all_internal;
623
bool m_was_one_shot;
624
};
625
626
// StopInfoWatchpoint
627
628
class StopInfoWatchpoint : public StopInfo {
629
public:
630
// Make sure watchpoint is properly disabled and subsequently enabled while
631
// performing watchpoint actions.
632
class WatchpointSentry {
633
public:
634
WatchpointSentry(ProcessSP p_sp, WatchpointSP w_sp) : process_sp(p_sp),
635
watchpoint_sp(w_sp) {
636
if (process_sp && watchpoint_sp) {
637
const bool notify = false;
638
watchpoint_sp->TurnOnEphemeralMode();
639
process_sp->DisableWatchpoint(watchpoint_sp, notify);
640
process_sp->AddPreResumeAction(SentryPreResumeAction, this);
641
}
642
}
643
644
void DoReenable() {
645
if (process_sp && watchpoint_sp) {
646
bool was_disabled = watchpoint_sp->IsDisabledDuringEphemeralMode();
647
watchpoint_sp->TurnOffEphemeralMode();
648
const bool notify = false;
649
if (was_disabled) {
650
process_sp->DisableWatchpoint(watchpoint_sp, notify);
651
} else {
652
process_sp->EnableWatchpoint(watchpoint_sp, notify);
653
}
654
}
655
}
656
657
~WatchpointSentry() {
658
DoReenable();
659
if (process_sp)
660
process_sp->ClearPreResumeAction(SentryPreResumeAction, this);
661
}
662
663
static bool SentryPreResumeAction(void *sentry_void) {
664
WatchpointSentry *sentry = (WatchpointSentry *) sentry_void;
665
sentry->DoReenable();
666
return true;
667
}
668
669
private:
670
ProcessSP process_sp;
671
WatchpointSP watchpoint_sp;
672
};
673
674
StopInfoWatchpoint(Thread &thread, break_id_t watch_id, bool silently_skip_wp)
675
: StopInfo(thread, watch_id), m_silently_skip_wp(silently_skip_wp) {}
676
677
~StopInfoWatchpoint() override = default;
678
679
StopReason GetStopReason() const override { return eStopReasonWatchpoint; }
680
681
const char *GetDescription() override {
682
if (m_description.empty()) {
683
StreamString strm;
684
strm.Printf("watchpoint %" PRIi64, m_value);
685
m_description = std::string(strm.GetString());
686
}
687
return m_description.c_str();
688
}
689
690
protected:
691
using StopInfoWatchpointSP = std::shared_ptr<StopInfoWatchpoint>;
692
// This plan is used to orchestrate stepping over the watchpoint for
693
// architectures (e.g. ARM) that report the watch before running the watched
694
// access. This is the sort of job you have to defer to the thread plans,
695
// if you try to do it directly in the stop info and there are other threads
696
// that needed to process this stop you will have yanked control away from
697
// them and they won't behave correctly.
698
class ThreadPlanStepOverWatchpoint : public ThreadPlanStepInstruction {
699
public:
700
ThreadPlanStepOverWatchpoint(Thread &thread,
701
StopInfoWatchpointSP stop_info_sp,
702
WatchpointSP watch_sp)
703
: ThreadPlanStepInstruction(thread, false, true, eVoteNoOpinion,
704
eVoteNoOpinion),
705
m_stop_info_sp(stop_info_sp), m_watch_sp(watch_sp) {
706
assert(watch_sp);
707
}
708
709
bool DoWillResume(lldb::StateType resume_state,
710
bool current_plan) override {
711
if (resume_state == eStateSuspended)
712
return true;
713
714
if (!m_did_disable_wp) {
715
GetThread().GetProcess()->DisableWatchpoint(m_watch_sp, false);
716
m_did_disable_wp = true;
717
}
718
return true;
719
}
720
721
bool DoPlanExplainsStop(Event *event_ptr) override {
722
if (ThreadPlanStepInstruction::DoPlanExplainsStop(event_ptr))
723
return true;
724
StopInfoSP stop_info_sp = GetThread().GetPrivateStopInfo();
725
// lldb-server resets the stop info for threads that didn't get to run,
726
// so we might have not gotten to run, but still have a watchpoint stop
727
// reason, in which case this will indeed be for us.
728
if (stop_info_sp
729
&& stop_info_sp->GetStopReason() == eStopReasonWatchpoint)
730
return true;
731
return false;
732
}
733
734
void DidPop() override {
735
// Don't artifically keep the watchpoint alive.
736
m_watch_sp.reset();
737
}
738
739
bool ShouldStop(Event *event_ptr) override {
740
bool should_stop = ThreadPlanStepInstruction::ShouldStop(event_ptr);
741
bool plan_done = MischiefManaged();
742
if (plan_done) {
743
m_stop_info_sp->SetStepOverPlanComplete();
744
GetThread().SetStopInfo(m_stop_info_sp);
745
ResetWatchpoint();
746
}
747
return should_stop;
748
}
749
750
bool ShouldRunBeforePublicStop() override {
751
return true;
752
}
753
754
protected:
755
void ResetWatchpoint() {
756
if (!m_did_disable_wp)
757
return;
758
m_did_disable_wp = true;
759
GetThread().GetProcess()->EnableWatchpoint(m_watch_sp, true);
760
}
761
762
private:
763
StopInfoWatchpointSP m_stop_info_sp;
764
WatchpointSP m_watch_sp;
765
bool m_did_disable_wp = false;
766
};
767
768
bool ShouldStopSynchronous(Event *event_ptr) override {
769
// If we are running our step-over the watchpoint plan, stop if it's done
770
// and continue if it's not:
771
if (m_should_stop_is_valid)
772
return m_should_stop;
773
774
// If we are running our step over plan, then stop here and let the regular
775
// ShouldStop figure out what we should do: Otherwise, give our plan
776
// more time to get run:
777
if (m_using_step_over_plan)
778
return m_step_over_plan_complete;
779
780
Log *log = GetLog(LLDBLog::Process);
781
ThreadSP thread_sp(m_thread_wp.lock());
782
assert(thread_sp);
783
784
if (thread_sp->GetTemporaryResumeState() == eStateSuspended) {
785
// This is the second firing of a watchpoint so don't process it again.
786
LLDB_LOG(log, "We didn't run but stopped with a StopInfoWatchpoint, we "
787
"have already handled this one, don't do it again.");
788
m_should_stop = false;
789
m_should_stop_is_valid = true;
790
return m_should_stop;
791
}
792
793
WatchpointSP wp_sp(
794
thread_sp->CalculateTarget()->GetWatchpointList().FindByID(GetValue()));
795
// If we can no longer find the watchpoint, we just have to stop:
796
if (!wp_sp) {
797
798
LLDB_LOGF(log,
799
"Process::%s could not find watchpoint location id: %" PRId64
800
"...",
801
__FUNCTION__, GetValue());
802
803
m_should_stop = true;
804
m_should_stop_is_valid = true;
805
return true;
806
}
807
808
ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
809
StoppointCallbackContext context(event_ptr, exe_ctx, true);
810
m_should_stop = wp_sp->ShouldStop(&context);
811
if (!m_should_stop) {
812
// This won't happen at present because we only allow one watchpoint per
813
// watched range. So we won't stop at a watched address with a disabled
814
// watchpoint. If we start allowing overlapping watchpoints, then we
815
// will have to make watchpoints be real "WatchpointSite" and delegate to
816
// all the watchpoints sharing the site. In that case, the code below
817
// would be the right thing to do.
818
m_should_stop_is_valid = true;
819
return m_should_stop;
820
}
821
// If this is a system where we need to execute the watchpoint by hand
822
// after the hit, queue a thread plan to do that, and then say not to stop.
823
// Otherwise, let the async action figure out whether the watchpoint should
824
// stop
825
826
ProcessSP process_sp = exe_ctx.GetProcessSP();
827
bool wp_triggers_after = process_sp->GetWatchpointReportedAfter();
828
829
if (!wp_triggers_after) {
830
// We have to step over the watchpoint before we know what to do:
831
StopInfoWatchpointSP me_as_siwp_sp
832
= std::static_pointer_cast<StopInfoWatchpoint>(shared_from_this());
833
ThreadPlanSP step_over_wp_sp(new ThreadPlanStepOverWatchpoint(
834
*(thread_sp.get()), me_as_siwp_sp, wp_sp));
835
// When this plan is done we want to stop, so set this as a Controlling
836
// plan.
837
step_over_wp_sp->SetIsControllingPlan(true);
838
step_over_wp_sp->SetOkayToDiscard(false);
839
840
Status error;
841
error = thread_sp->QueueThreadPlan(step_over_wp_sp, false);
842
// If we couldn't push the thread plan, just stop here:
843
if (!error.Success()) {
844
LLDB_LOGF(log, "Could not push our step over watchpoint plan: %s",
845
error.AsCString());
846
847
m_should_stop = true;
848
m_should_stop_is_valid = true;
849
return true;
850
} else {
851
// Otherwise, don't set m_should_stop, we don't know that yet. Just
852
// say we should continue, and tell the thread we really should do so:
853
thread_sp->SetShouldRunBeforePublicStop(true);
854
m_using_step_over_plan = true;
855
return false;
856
}
857
} else {
858
// We didn't have to do anything special
859
m_should_stop_is_valid = true;
860
return m_should_stop;
861
}
862
863
return m_should_stop;
864
}
865
866
bool ShouldStop(Event *event_ptr) override {
867
// This just reports the work done by PerformAction or the synchronous
868
// stop. It should only ever get called after they have had a chance to
869
// run.
870
assert(m_should_stop_is_valid);
871
return m_should_stop;
872
}
873
874
void PerformAction(Event *event_ptr) override {
875
Log *log = GetLog(LLDBLog::Watchpoints);
876
// We're going to calculate if we should stop or not in some way during the
877
// course of this code. Also by default we're going to stop, so set that
878
// here.
879
m_should_stop = true;
880
881
882
ThreadSP thread_sp(m_thread_wp.lock());
883
if (thread_sp) {
884
885
WatchpointSP wp_sp(
886
thread_sp->CalculateTarget()->GetWatchpointList().FindByID(
887
GetValue()));
888
if (wp_sp) {
889
// This sentry object makes sure the current watchpoint is disabled
890
// while performing watchpoint actions, and it is then enabled after we
891
// are finished.
892
ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
893
ProcessSP process_sp = exe_ctx.GetProcessSP();
894
895
WatchpointSentry sentry(process_sp, wp_sp);
896
897
if (m_silently_skip_wp) {
898
m_should_stop = false;
899
wp_sp->UndoHitCount();
900
}
901
902
if (wp_sp->GetHitCount() <= wp_sp->GetIgnoreCount()) {
903
m_should_stop = false;
904
m_should_stop_is_valid = true;
905
}
906
907
Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
908
909
if (m_should_stop && wp_sp->GetConditionText() != nullptr) {
910
// We need to make sure the user sees any parse errors in their
911
// condition, so we'll hook the constructor errors up to the
912
// debugger's Async I/O.
913
ExpressionResults result_code;
914
EvaluateExpressionOptions expr_options;
915
expr_options.SetUnwindOnError(true);
916
expr_options.SetIgnoreBreakpoints(true);
917
ValueObjectSP result_value_sp;
918
Status error;
919
result_code = UserExpression::Evaluate(
920
exe_ctx, expr_options, wp_sp->GetConditionText(),
921
llvm::StringRef(), result_value_sp, error);
922
923
if (result_code == eExpressionCompleted) {
924
if (result_value_sp) {
925
Scalar scalar_value;
926
if (result_value_sp->ResolveValue(scalar_value)) {
927
if (scalar_value.ULongLong(1) == 0) {
928
// The condition failed, which we consider "not having hit
929
// the watchpoint" so undo the hit count here.
930
wp_sp->UndoHitCount();
931
m_should_stop = false;
932
} else
933
m_should_stop = true;
934
LLDB_LOGF(log,
935
"Condition successfully evaluated, result is %s.\n",
936
m_should_stop ? "true" : "false");
937
} else {
938
m_should_stop = true;
939
LLDB_LOGF(
940
log,
941
"Failed to get an integer result from the expression.");
942
}
943
}
944
} else {
945
const char *err_str = error.AsCString("<unknown error>");
946
LLDB_LOGF(log, "Error evaluating condition: \"%s\"\n", err_str);
947
948
StreamString strm;
949
strm << "stopped due to an error evaluating condition of "
950
"watchpoint ";
951
wp_sp->GetDescription(&strm, eDescriptionLevelBrief);
952
strm << ": \"" << wp_sp->GetConditionText() << "\"\n";
953
strm << err_str;
954
955
Debugger::ReportError(strm.GetString().str(),
956
exe_ctx.GetTargetRef().GetDebugger().GetID());
957
}
958
}
959
960
// If the condition says to stop, we run the callback to further decide
961
// whether to stop.
962
if (m_should_stop) {
963
// FIXME: For now the callbacks have to run in async mode - the
964
// first time we restart we need
965
// to get out of there. So set it here.
966
// When we figure out how to nest watchpoint hits then this will
967
// change.
968
969
bool old_async = debugger.GetAsyncExecution();
970
debugger.SetAsyncExecution(true);
971
972
StoppointCallbackContext context(event_ptr, exe_ctx, false);
973
bool stop_requested = wp_sp->InvokeCallback(&context);
974
975
debugger.SetAsyncExecution(old_async);
976
977
// Also make sure that the callback hasn't continued the target. If
978
// it did, when we'll set m_should_stop to false and get out of here.
979
if (HasTargetRunSinceMe())
980
m_should_stop = false;
981
982
if (m_should_stop && !stop_requested) {
983
// We have been vetoed by the callback mechanism.
984
m_should_stop = false;
985
}
986
}
987
988
// Don't stop if the watched region value is unmodified, and
989
// this is a Modify-type watchpoint.
990
if (m_should_stop && !wp_sp->WatchedValueReportable(exe_ctx)) {
991
wp_sp->UndoHitCount();
992
m_should_stop = false;
993
}
994
995
// Finally, if we are going to stop, print out the new & old values:
996
if (m_should_stop) {
997
wp_sp->CaptureWatchedValue(exe_ctx);
998
999
Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
1000
StreamSP output_sp = debugger.GetAsyncOutputStream();
1001
if (wp_sp->DumpSnapshots(output_sp.get())) {
1002
output_sp->EOL();
1003
output_sp->Flush();
1004
}
1005
}
1006
1007
} else {
1008
Log *log_process(GetLog(LLDBLog::Process));
1009
1010
LLDB_LOGF(log_process,
1011
"Process::%s could not find watchpoint id: %" PRId64 "...",
1012
__FUNCTION__, m_value);
1013
}
1014
LLDB_LOGF(log,
1015
"Process::%s returning from action with m_should_stop: %d.",
1016
__FUNCTION__, m_should_stop);
1017
1018
m_should_stop_is_valid = true;
1019
}
1020
}
1021
1022
private:
1023
void SetStepOverPlanComplete() {
1024
assert(m_using_step_over_plan);
1025
m_step_over_plan_complete = true;
1026
}
1027
1028
bool m_should_stop = false;
1029
bool m_should_stop_is_valid = false;
1030
// A false watchpoint hit has happened -
1031
// the thread stopped with a watchpoint
1032
// hit notification, but the watched region
1033
// was not actually accessed (as determined
1034
// by the gdb stub we're talking to).
1035
// Continue past this watchpoint without
1036
// notifying the user; on some targets this
1037
// may mean disable wp, instruction step,
1038
// re-enable wp, continue.
1039
// On others, just continue.
1040
bool m_silently_skip_wp = false;
1041
bool m_step_over_plan_complete = false;
1042
bool m_using_step_over_plan = false;
1043
};
1044
1045
// StopInfoUnixSignal
1046
1047
class StopInfoUnixSignal : public StopInfo {
1048
public:
1049
StopInfoUnixSignal(Thread &thread, int signo, const char *description,
1050
std::optional<int> code)
1051
: StopInfo(thread, signo), m_code(code) {
1052
SetDescription(description);
1053
}
1054
1055
~StopInfoUnixSignal() override = default;
1056
1057
StopReason GetStopReason() const override { return eStopReasonSignal; }
1058
1059
bool ShouldStopSynchronous(Event *event_ptr) override {
1060
ThreadSP thread_sp(m_thread_wp.lock());
1061
if (thread_sp)
1062
return thread_sp->GetProcess()->GetUnixSignals()->GetShouldStop(m_value);
1063
return false;
1064
}
1065
1066
bool ShouldStop(Event *event_ptr) override {
1067
ThreadSP thread_sp(m_thread_wp.lock());
1068
if (thread_sp)
1069
return thread_sp->GetProcess()->GetUnixSignals()->GetShouldStop(m_value);
1070
return false;
1071
}
1072
1073
// If should stop returns false, check if we should notify of this event
1074
bool DoShouldNotify(Event *event_ptr) override {
1075
ThreadSP thread_sp(m_thread_wp.lock());
1076
if (thread_sp) {
1077
bool should_notify =
1078
thread_sp->GetProcess()->GetUnixSignals()->GetShouldNotify(m_value);
1079
if (should_notify) {
1080
StreamString strm;
1081
strm.Format(
1082
"thread {0:d} received signal: {1}", thread_sp->GetIndexID(),
1083
thread_sp->GetProcess()->GetUnixSignals()->GetSignalAsStringRef(
1084
m_value));
1085
Process::ProcessEventData::AddRestartedReason(event_ptr,
1086
strm.GetData());
1087
}
1088
return should_notify;
1089
}
1090
return true;
1091
}
1092
1093
void WillResume(lldb::StateType resume_state) override {
1094
ThreadSP thread_sp(m_thread_wp.lock());
1095
if (thread_sp) {
1096
if (!thread_sp->GetProcess()->GetUnixSignals()->GetShouldSuppress(
1097
m_value))
1098
thread_sp->SetResumeSignal(m_value);
1099
}
1100
}
1101
1102
const char *GetDescription() override {
1103
if (m_description.empty()) {
1104
ThreadSP thread_sp(m_thread_wp.lock());
1105
if (thread_sp) {
1106
UnixSignalsSP unix_signals = thread_sp->GetProcess()->GetUnixSignals();
1107
StreamString strm;
1108
strm << "signal ";
1109
1110
std::string signal_name =
1111
unix_signals->GetSignalDescription(m_value, m_code);
1112
if (signal_name.size())
1113
strm << signal_name;
1114
else
1115
strm.Printf("%" PRIi64, m_value);
1116
1117
m_description = std::string(strm.GetString());
1118
}
1119
}
1120
return m_description.c_str();
1121
}
1122
1123
private:
1124
// In siginfo_t terms, if m_value is si_signo, m_code is si_code.
1125
std::optional<int> m_code;
1126
};
1127
1128
// StopInfoTrace
1129
1130
class StopInfoTrace : public StopInfo {
1131
public:
1132
StopInfoTrace(Thread &thread) : StopInfo(thread, LLDB_INVALID_UID) {}
1133
1134
~StopInfoTrace() override = default;
1135
1136
StopReason GetStopReason() const override { return eStopReasonTrace; }
1137
1138
const char *GetDescription() override {
1139
if (m_description.empty())
1140
return "trace";
1141
else
1142
return m_description.c_str();
1143
}
1144
};
1145
1146
// StopInfoException
1147
1148
class StopInfoException : public StopInfo {
1149
public:
1150
StopInfoException(Thread &thread, const char *description)
1151
: StopInfo(thread, LLDB_INVALID_UID) {
1152
if (description)
1153
SetDescription(description);
1154
}
1155
1156
~StopInfoException() override = default;
1157
1158
StopReason GetStopReason() const override { return eStopReasonException; }
1159
1160
const char *GetDescription() override {
1161
if (m_description.empty())
1162
return "exception";
1163
else
1164
return m_description.c_str();
1165
}
1166
};
1167
1168
// StopInfoProcessorTrace
1169
1170
class StopInfoProcessorTrace : public StopInfo {
1171
public:
1172
StopInfoProcessorTrace(Thread &thread, const char *description)
1173
: StopInfo(thread, LLDB_INVALID_UID) {
1174
if (description)
1175
SetDescription(description);
1176
}
1177
1178
~StopInfoProcessorTrace() override = default;
1179
1180
StopReason GetStopReason() const override {
1181
return eStopReasonProcessorTrace;
1182
}
1183
1184
const char *GetDescription() override {
1185
if (m_description.empty())
1186
return "processor trace event";
1187
else
1188
return m_description.c_str();
1189
}
1190
};
1191
1192
// StopInfoThreadPlan
1193
1194
class StopInfoThreadPlan : public StopInfo {
1195
public:
1196
StopInfoThreadPlan(ThreadPlanSP &plan_sp, ValueObjectSP &return_valobj_sp,
1197
ExpressionVariableSP &expression_variable_sp)
1198
: StopInfo(plan_sp->GetThread(), LLDB_INVALID_UID), m_plan_sp(plan_sp),
1199
m_return_valobj_sp(return_valobj_sp),
1200
m_expression_variable_sp(expression_variable_sp) {}
1201
1202
~StopInfoThreadPlan() override = default;
1203
1204
StopReason GetStopReason() const override { return eStopReasonPlanComplete; }
1205
1206
const char *GetDescription() override {
1207
if (m_description.empty()) {
1208
StreamString strm;
1209
m_plan_sp->GetDescription(&strm, eDescriptionLevelBrief);
1210
m_description = std::string(strm.GetString());
1211
}
1212
return m_description.c_str();
1213
}
1214
1215
ValueObjectSP GetReturnValueObject() { return m_return_valobj_sp; }
1216
1217
ExpressionVariableSP GetExpressionVariable() {
1218
return m_expression_variable_sp;
1219
}
1220
1221
protected:
1222
bool ShouldStop(Event *event_ptr) override {
1223
if (m_plan_sp)
1224
return m_plan_sp->ShouldStop(event_ptr);
1225
else
1226
return StopInfo::ShouldStop(event_ptr);
1227
}
1228
1229
private:
1230
ThreadPlanSP m_plan_sp;
1231
ValueObjectSP m_return_valobj_sp;
1232
ExpressionVariableSP m_expression_variable_sp;
1233
};
1234
1235
// StopInfoExec
1236
1237
class StopInfoExec : public StopInfo {
1238
public:
1239
StopInfoExec(Thread &thread) : StopInfo(thread, LLDB_INVALID_UID) {}
1240
1241
~StopInfoExec() override = default;
1242
1243
bool ShouldStop(Event *event_ptr) override {
1244
ThreadSP thread_sp(m_thread_wp.lock());
1245
if (thread_sp)
1246
return thread_sp->GetProcess()->GetStopOnExec();
1247
return false;
1248
}
1249
1250
StopReason GetStopReason() const override { return eStopReasonExec; }
1251
1252
const char *GetDescription() override { return "exec"; }
1253
1254
protected:
1255
void PerformAction(Event *event_ptr) override {
1256
// Only perform the action once
1257
if (m_performed_action)
1258
return;
1259
m_performed_action = true;
1260
ThreadSP thread_sp(m_thread_wp.lock());
1261
if (thread_sp)
1262
thread_sp->GetProcess()->DidExec();
1263
}
1264
1265
bool m_performed_action = false;
1266
};
1267
1268
// StopInfoFork
1269
1270
class StopInfoFork : public StopInfo {
1271
public:
1272
StopInfoFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
1273
: StopInfo(thread, child_pid), m_child_pid(child_pid),
1274
m_child_tid(child_tid) {}
1275
1276
~StopInfoFork() override = default;
1277
1278
bool ShouldStop(Event *event_ptr) override { return false; }
1279
1280
StopReason GetStopReason() const override { return eStopReasonFork; }
1281
1282
const char *GetDescription() override { return "fork"; }
1283
1284
protected:
1285
void PerformAction(Event *event_ptr) override {
1286
// Only perform the action once
1287
if (m_performed_action)
1288
return;
1289
m_performed_action = true;
1290
ThreadSP thread_sp(m_thread_wp.lock());
1291
if (thread_sp)
1292
thread_sp->GetProcess()->DidFork(m_child_pid, m_child_tid);
1293
}
1294
1295
bool m_performed_action = false;
1296
1297
private:
1298
lldb::pid_t m_child_pid;
1299
lldb::tid_t m_child_tid;
1300
};
1301
1302
// StopInfoVFork
1303
1304
class StopInfoVFork : public StopInfo {
1305
public:
1306
StopInfoVFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
1307
: StopInfo(thread, child_pid), m_child_pid(child_pid),
1308
m_child_tid(child_tid) {}
1309
1310
~StopInfoVFork() override = default;
1311
1312
bool ShouldStop(Event *event_ptr) override { return false; }
1313
1314
StopReason GetStopReason() const override { return eStopReasonVFork; }
1315
1316
const char *GetDescription() override { return "vfork"; }
1317
1318
protected:
1319
void PerformAction(Event *event_ptr) override {
1320
// Only perform the action once
1321
if (m_performed_action)
1322
return;
1323
m_performed_action = true;
1324
ThreadSP thread_sp(m_thread_wp.lock());
1325
if (thread_sp)
1326
thread_sp->GetProcess()->DidVFork(m_child_pid, m_child_tid);
1327
}
1328
1329
bool m_performed_action = false;
1330
1331
private:
1332
lldb::pid_t m_child_pid;
1333
lldb::tid_t m_child_tid;
1334
};
1335
1336
// StopInfoVForkDone
1337
1338
class StopInfoVForkDone : public StopInfo {
1339
public:
1340
StopInfoVForkDone(Thread &thread) : StopInfo(thread, 0) {}
1341
1342
~StopInfoVForkDone() override = default;
1343
1344
bool ShouldStop(Event *event_ptr) override { return false; }
1345
1346
StopReason GetStopReason() const override { return eStopReasonVForkDone; }
1347
1348
const char *GetDescription() override { return "vforkdone"; }
1349
1350
protected:
1351
void PerformAction(Event *event_ptr) override {
1352
// Only perform the action once
1353
if (m_performed_action)
1354
return;
1355
m_performed_action = true;
1356
ThreadSP thread_sp(m_thread_wp.lock());
1357
if (thread_sp)
1358
thread_sp->GetProcess()->DidVForkDone();
1359
}
1360
1361
bool m_performed_action = false;
1362
};
1363
1364
} // namespace lldb_private
1365
1366
StopInfoSP StopInfo::CreateStopReasonWithBreakpointSiteID(Thread &thread,
1367
break_id_t break_id) {
1368
return StopInfoSP(new StopInfoBreakpoint(thread, break_id));
1369
}
1370
1371
StopInfoSP StopInfo::CreateStopReasonWithBreakpointSiteID(Thread &thread,
1372
break_id_t break_id,
1373
bool should_stop) {
1374
return StopInfoSP(new StopInfoBreakpoint(thread, break_id, should_stop));
1375
}
1376
1377
// LWP_TODO: We'll need a CreateStopReasonWithWatchpointResourceID akin
1378
// to CreateStopReasonWithBreakpointSiteID
1379
StopInfoSP StopInfo::CreateStopReasonWithWatchpointID(Thread &thread,
1380
break_id_t watch_id,
1381
bool silently_continue) {
1382
return StopInfoSP(
1383
new StopInfoWatchpoint(thread, watch_id, silently_continue));
1384
}
1385
1386
StopInfoSP StopInfo::CreateStopReasonWithSignal(Thread &thread, int signo,
1387
const char *description,
1388
std::optional<int> code) {
1389
thread.GetProcess()->GetUnixSignals()->IncrementSignalHitCount(signo);
1390
return StopInfoSP(new StopInfoUnixSignal(thread, signo, description, code));
1391
}
1392
1393
StopInfoSP StopInfo::CreateStopReasonToTrace(Thread &thread) {
1394
return StopInfoSP(new StopInfoTrace(thread));
1395
}
1396
1397
StopInfoSP StopInfo::CreateStopReasonWithPlan(
1398
ThreadPlanSP &plan_sp, ValueObjectSP return_valobj_sp,
1399
ExpressionVariableSP expression_variable_sp) {
1400
return StopInfoSP(new StopInfoThreadPlan(plan_sp, return_valobj_sp,
1401
expression_variable_sp));
1402
}
1403
1404
StopInfoSP StopInfo::CreateStopReasonWithException(Thread &thread,
1405
const char *description) {
1406
return StopInfoSP(new StopInfoException(thread, description));
1407
}
1408
1409
StopInfoSP StopInfo::CreateStopReasonProcessorTrace(Thread &thread,
1410
const char *description) {
1411
return StopInfoSP(new StopInfoProcessorTrace(thread, description));
1412
}
1413
1414
StopInfoSP StopInfo::CreateStopReasonWithExec(Thread &thread) {
1415
return StopInfoSP(new StopInfoExec(thread));
1416
}
1417
1418
StopInfoSP StopInfo::CreateStopReasonFork(Thread &thread,
1419
lldb::pid_t child_pid,
1420
lldb::tid_t child_tid) {
1421
return StopInfoSP(new StopInfoFork(thread, child_pid, child_tid));
1422
}
1423
1424
1425
StopInfoSP StopInfo::CreateStopReasonVFork(Thread &thread,
1426
lldb::pid_t child_pid,
1427
lldb::tid_t child_tid) {
1428
return StopInfoSP(new StopInfoVFork(thread, child_pid, child_tid));
1429
}
1430
1431
StopInfoSP StopInfo::CreateStopReasonVForkDone(Thread &thread) {
1432
return StopInfoSP(new StopInfoVForkDone(thread));
1433
}
1434
1435
ValueObjectSP StopInfo::GetReturnValueObject(StopInfoSP &stop_info_sp) {
1436
if (stop_info_sp &&
1437
stop_info_sp->GetStopReason() == eStopReasonPlanComplete) {
1438
StopInfoThreadPlan *plan_stop_info =
1439
static_cast<StopInfoThreadPlan *>(stop_info_sp.get());
1440
return plan_stop_info->GetReturnValueObject();
1441
} else
1442
return ValueObjectSP();
1443
}
1444
1445
ExpressionVariableSP StopInfo::GetExpressionVariable(StopInfoSP &stop_info_sp) {
1446
if (stop_info_sp &&
1447
stop_info_sp->GetStopReason() == eStopReasonPlanComplete) {
1448
StopInfoThreadPlan *plan_stop_info =
1449
static_cast<StopInfoThreadPlan *>(stop_info_sp.get());
1450
return plan_stop_info->GetExpressionVariable();
1451
} else
1452
return ExpressionVariableSP();
1453
}
1454
1455
lldb::ValueObjectSP
1456
StopInfo::GetCrashingDereference(StopInfoSP &stop_info_sp,
1457
lldb::addr_t *crashing_address) {
1458
if (!stop_info_sp) {
1459
return ValueObjectSP();
1460
}
1461
1462
const char *description = stop_info_sp->GetDescription();
1463
if (!description) {
1464
return ValueObjectSP();
1465
}
1466
1467
ThreadSP thread_sp = stop_info_sp->GetThread();
1468
if (!thread_sp) {
1469
return ValueObjectSP();
1470
}
1471
1472
StackFrameSP frame_sp =
1473
thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame);
1474
1475
if (!frame_sp) {
1476
return ValueObjectSP();
1477
}
1478
1479
const char address_string[] = "address=";
1480
1481
const char *address_loc = strstr(description, address_string);
1482
if (!address_loc) {
1483
return ValueObjectSP();
1484
}
1485
1486
address_loc += (sizeof(address_string) - 1);
1487
1488
uint64_t address = strtoull(address_loc, nullptr, 0);
1489
if (crashing_address) {
1490
*crashing_address = address;
1491
}
1492
1493
return frame_sp->GuessValueForAddress(address);
1494
}
1495
1496