Skip to content

Commit f08f5c9

Browse files
committed
Add an auto-continue flag to breakpoints & locations.
You can get a breakpoint to auto-continue by adding "continue" as a command, but that has the disadvantage that if you hit two breakpoints simultaneously, the continue will force the process to continue, and maybe even forstalling the commands on the other. The auto-continue flag means the breakpoints can negotiate about whether to stop. Writing tests, I wanted to supply some commands when I made the breakpoints, so I also added that ability. llvm-svn: 309969
1 parent f0cadcd commit f08f5c9

File tree

16 files changed

+273
-29
lines changed

16 files changed

+273
-29
lines changed

lldb/include/lldb/API/SBBreakpoint.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ class LLDB_API SBBreakpoint {
7070

7171
const char *GetCondition();
7272

73+
void SetAutoContinue(bool auto_continue);
74+
75+
bool GetAutoContinue();
76+
7377
void SetThreadID(lldb::tid_t sb_thread_id);
7478

7579
lldb::tid_t GetThreadID();

lldb/include/lldb/API/SBBreakpointLocation.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ class LLDB_API SBBreakpointLocation {
4747
void SetCondition(const char *condition);
4848

4949
const char *GetCondition();
50+
51+
void SetAutoContinue(bool auto_continue);
52+
53+
bool GetAutoContinue();
5054

5155
void SetScriptCallbackFunction(const char *callback_function_name);
5256

lldb/include/lldb/Breakpoint/Breakpoint.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,18 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
420420
//------------------------------------------------------------------
421421
bool IsOneShot() const;
422422

423+
//------------------------------------------------------------------
424+
/// If \a auto_continue is \b true, breakpoint will auto-continue when on hit.
425+
//------------------------------------------------------------------
426+
void SetAutoContinue(bool auto_continue);
427+
428+
//------------------------------------------------------------------
429+
/// Check the AutoContinue state.
430+
/// @return
431+
/// \b true if the breakpoint is set to auto-continue, \b false otherwise.
432+
//------------------------------------------------------------------
433+
bool IsAutoContinue() const;
434+
423435
//------------------------------------------------------------------
424436
/// Set the valid thread to be checked when the breakpoint is hit.
425437
/// @param[in] thread_id

lldb/include/lldb/Breakpoint/BreakpointLocation.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,19 @@ class BreakpointLocation
106106
//------------------------------------------------------------------
107107
bool IsEnabled() const;
108108

109+
//------------------------------------------------------------------
110+
/// If \a auto_continue is \b true, set the breakpoint to continue when hit.
111+
//------------------------------------------------------------------
112+
void SetAutoContinue(bool auto_continue);
113+
114+
//------------------------------------------------------------------
115+
/// Check the AutoContinue state.
116+
///
117+
/// @return
118+
/// \b true if the breakpoint is set to auto-continue, \b false if not.
119+
//------------------------------------------------------------------
120+
bool IsAutoContinue() const;
121+
109122
//------------------------------------------------------------------
110123
/// Return the current Ignore Count.
111124
///

lldb/include/lldb/Breakpoint/BreakpointOptions.h

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,13 @@ friend class Breakpoint;
3838

3939
public:
4040
enum OptionKind {
41-
eCallback = 1 << 0,
42-
eEnabled = 1 << 1,
43-
eOneShot = 1 << 2,
44-
eIgnoreCount = 1 << 3,
45-
eThreadSpec = 1 << 4,
46-
eCondition = 1 << 5
41+
eCallback = 1 << 0,
42+
eEnabled = 1 << 1,
43+
eOneShot = 1 << 2,
44+
eIgnoreCount = 1 << 3,
45+
eThreadSpec = 1 << 4,
46+
eCondition = 1 << 5,
47+
eAutoContinue = 1 << 6
4748
};
4849
struct CommandData {
4950
CommandData()
@@ -112,7 +113,8 @@ friend class Breakpoint;
112113
///
113114
//------------------------------------------------------------------
114115
BreakpointOptions(const char *condition, bool enabled = true,
115-
int32_t ignore = 0, bool one_shot = false);
116+
int32_t ignore = 0, bool one_shot = false,
117+
bool auto_continue = false);
116118

117119
virtual ~BreakpointOptions();
118120

@@ -295,6 +297,21 @@ friend class Breakpoint;
295297
m_set_flags.Set(eEnabled);
296298
}
297299

300+
//------------------------------------------------------------------
301+
/// Check the auto-continue state.
302+
/// @return
303+
/// \b true if the breakpoint is set to auto-continue, \b false otherwise.
304+
//------------------------------------------------------------------
305+
bool IsAutoContinue() const { return m_auto_continue; }
306+
307+
//------------------------------------------------------------------
308+
/// Set the auto-continue state.
309+
//------------------------------------------------------------------
310+
void SetAutoContinue(bool auto_continue) {
311+
m_auto_continue = auto_continue;
312+
m_set_flags.Set(eAutoContinue);
313+
}
314+
298315
//------------------------------------------------------------------
299316
/// Check the One-shot state.
300317
/// @return
@@ -394,6 +411,7 @@ friend class Breakpoint;
394411
IgnoreCount,
395412
EnabledState,
396413
OneShotState,
414+
AutoContinue,
397415
LastOptionName
398416
};
399417
static const char *g_option_names[(size_t)OptionNames::LastOptionName];
@@ -424,6 +442,7 @@ friend class Breakpoint;
424442
std::string m_condition_text; // The condition to test.
425443
size_t m_condition_text_hash; // Its hash, so that locations know when the
426444
// condition is updated.
445+
bool m_auto_continue; // If set, auto-continue from breakpoint.
427446
Flags m_set_flags; // Which options are set at this level. Drawn
428447
// from BreakpointOptions::SetOptionsFlags.
429448
};

lldb/include/lldb/lldb-enumerations.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,8 @@ FLAGS_ENUM(BreakpointEventType){
380380
eBreakpointEventTypeCommandChanged = (1u << 8),
381381
eBreakpointEventTypeConditionChanged = (1u << 9),
382382
eBreakpointEventTypeIgnoreChanged = (1u << 10),
383-
eBreakpointEventTypeThreadChanged = (1u << 11)};
383+
eBreakpointEventTypeThreadChanged = (1u << 11),
384+
eBreakpointEventTypeAutoContinueChanged = (1u << 12)};
384385

385386
FLAGS_ENUM(WatchpointEventType){
386387
eWatchpointEventTypeInvalidType = (1u << 0),
@@ -566,6 +567,7 @@ enum CommandArgumentType {
566567
eArgTypeWatchpointIDRange,
567568
eArgTypeWatchType,
568569
eArgRawInput,
570+
eArgTypeCommand,
569571
eArgTypeLastArg // Always keep this entry as the last entry in this
570572
// enumeration!!
571573
};

lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,21 @@ def classCleanup(cls):
2424
cls.RemoveTempFile("output2.txt")
2525

2626
@expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
27-
def test(self):
27+
def test_breakpoint_command_sequence(self):
2828
"""Test a sequence of breakpoint command add, list, and delete."""
2929
self.build()
3030
self.breakpoint_command_sequence()
31+
32+
@expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
33+
def test_script_parameters(self):
34+
"""Test a sequence of breakpoint command add, list, and delete."""
35+
self.build()
3136
self.breakpoint_command_script_parameters()
3237

38+
def test_commands_on_creation(self):
39+
self.build()
40+
self.breakpoint_commands_on_creation()
41+
3342
def setUp(self):
3443
# Call super's setUp().
3544
TestBase.setUp(self)
@@ -268,3 +277,23 @@ def breakpoint_command_script_parameters(self):
268277

269278
# Now remove 'output-2.txt'
270279
os.remove('output-2.txt')
280+
281+
def breakpoint_commands_on_creation(self):
282+
"""Test that setting breakpoint commands when creating the breakpoint works"""
283+
exe = os.path.join(os.getcwd(), "a.out")
284+
target = self.dbg.CreateTarget(exe)
285+
self.assertTrue(target.IsValid(), "Created an invalid target.")
286+
287+
# Add a breakpoint.
288+
lldbutil.run_break_set_by_file_and_line(
289+
self, "main.c", self.line, num_expected_locations=1, loc_exact=True,
290+
extra_options='-d bt -d "thread list" -d continue')
291+
292+
bkpt = target.FindBreakpointByID(1)
293+
self.assertTrue(bkpt.IsValid(), "Couldn't find breakpoint 1")
294+
com_list = lldb.SBStringList()
295+
bkpt.GetCommandLineCommands(com_list)
296+
self.assertEqual(com_list.GetSize(), 3, "Got the wrong number of commands")
297+
self.assertEqual(com_list.GetStringAtIndex(0), "bt", "First bt")
298+
self.assertEqual(com_list.GetStringAtIndex(1), "thread list", "Next thread list")
299+
self.assertEqual(com_list.GetStringAtIndex(2), "continue", "Last continue")

lldb/scripts/interface/SBBreakpoint.i

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ public:
153153
const char *
154154
GetCondition ();
155155

156+
void SetAutoContinue(bool auto_continue);
157+
158+
bool GetAutoContinue();
159+
156160
void
157161
SetThreadID (lldb::tid_t sb_thread_id);
158162

lldb/scripts/interface/SBBreakpointLocation.i

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ public:
7373
const char *
7474
GetCondition ();
7575

76+
bool GetAutoContinue();
77+
78+
void SetAutoContinue(bool auto_continue);
79+
7680
%feature("docstring", "
7781
//------------------------------------------------------------------
7882
/// Set the callback to the given Python function name.

lldb/source/API/SBBreakpoint.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,25 @@ const char *SBBreakpoint::GetCondition() {
264264
return nullptr;
265265
}
266266

267+
void SBBreakpoint::SetAutoContinue(bool auto_continue) {
268+
BreakpointSP bkpt_sp = GetSP();
269+
if (bkpt_sp) {
270+
std::lock_guard<std::recursive_mutex> guard(
271+
bkpt_sp->GetTarget().GetAPIMutex());
272+
bkpt_sp->SetAutoContinue(auto_continue);
273+
}
274+
}
275+
276+
bool SBBreakpoint::GetAutoContinue() {
277+
BreakpointSP bkpt_sp = GetSP();
278+
if (bkpt_sp) {
279+
std::lock_guard<std::recursive_mutex> guard(
280+
bkpt_sp->GetTarget().GetAPIMutex());
281+
return bkpt_sp->IsAutoContinue();
282+
}
283+
return nullptr;
284+
}
285+
267286
uint32_t SBBreakpoint::GetHitCount() const {
268287
uint32_t count = 0;
269288
BreakpointSP bkpt_sp = GetSP();

lldb/source/API/SBBreakpointLocation.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,25 @@ const char *SBBreakpointLocation::GetCondition() {
149149
return NULL;
150150
}
151151

152+
void SBBreakpointLocation::SetAutoContinue(bool auto_continue) {
153+
BreakpointLocationSP loc_sp = GetSP();
154+
if (loc_sp) {
155+
std::lock_guard<std::recursive_mutex> guard(
156+
loc_sp->GetTarget().GetAPIMutex());
157+
loc_sp->SetAutoContinue(auto_continue);
158+
}
159+
}
160+
161+
bool SBBreakpointLocation::GetAutoContinue() {
162+
BreakpointLocationSP loc_sp = GetSP();
163+
if (loc_sp) {
164+
std::lock_guard<std::recursive_mutex> guard(
165+
loc_sp->GetTarget().GetAPIMutex());
166+
return loc_sp->IsAutoContinue();
167+
}
168+
return NULL;
169+
}
170+
152171
void SBBreakpointLocation::SetScriptCallbackFunction(
153172
const char *callback_function_name) {
154173
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

lldb/source/Breakpoint/Breakpoint.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,14 @@ void Breakpoint::SetOneShot(bool one_shot) {
348348
m_options_up->SetOneShot(one_shot);
349349
}
350350

351+
bool Breakpoint::IsAutoContinue() const {
352+
return m_options_up->IsAutoContinue();
353+
}
354+
355+
void Breakpoint::SetAutoContinue(bool auto_continue) {
356+
m_options_up->SetAutoContinue(auto_continue);
357+
}
358+
351359
void Breakpoint::SetThreadID(lldb::tid_t thread_id) {
352360
if (m_options_up->GetThreadSpec()->GetTID() == thread_id)
353361
return;

lldb/source/Breakpoint/BreakpointLocation.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,19 @@ void BreakpointLocation::SetEnabled(bool enabled) {
9393
: eBreakpointEventTypeDisabled);
9494
}
9595

96+
bool BreakpointLocation::IsAutoContinue() const {
97+
if (m_options_ap
98+
&& m_options_ap->IsOptionSet(BreakpointOptions::eAutoContinue))
99+
return m_options_ap->IsAutoContinue();
100+
else
101+
return m_owner.IsAutoContinue();
102+
}
103+
104+
void BreakpointLocation::SetAutoContinue(bool auto_continue) {
105+
GetLocationOptions()->SetAutoContinue(auto_continue);
106+
SendBreakpointLocationChangedEvent(eBreakpointEventTypeAutoContinueChanged);
107+
}
108+
96109
void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) {
97110
if (thread_id != LLDB_INVALID_THREAD_ID)
98111
GetLocationOptions()->SetThreadID(thread_id);

0 commit comments

Comments
 (0)