Add --move-to-nearest-code / target.move-to-nearest-code options (attempt 2)

This patch initially was committed in r237460 but later it was reverted (r237479) due to 4 new failures:
* TestExitDuringStep.py
* TestNumThreads.py
* TestThreadExit.py
* TestThreadStates.py

This patch also fixes these tests.

llvm-svn: 237566
This commit is contained in:
Ilia K 2015-05-18 13:41:01 +00:00
parent adba2aadf2
commit 055ad9beba
23 changed files with 241 additions and 43 deletions

View File

@ -32,7 +32,8 @@ public:
const FileSpec &resolver,
uint32_t line_no,
bool check_inlines,
bool skip_prologue);
bool skip_prologue,
bool exact_match);
virtual
~BreakpointResolverFileLine ();
@ -67,6 +68,7 @@ protected:
uint32_t m_line_number; // This is the line number that we are looking for.
bool m_inlines; // This determines whether the resolver looks for inlined functions or not.
bool m_skip_prologue;
bool m_exact_match;
private:
DISALLOW_COPY_AND_ASSIGN(BreakpointResolverFileLine);

View File

@ -29,7 +29,8 @@ class BreakpointResolverFileRegex :
{
public:
BreakpointResolverFileRegex (Breakpoint *bkpt,
RegularExpression &regex);
RegularExpression &regex,
bool exact_match);
virtual
~BreakpointResolverFileRegex ();
@ -61,6 +62,7 @@ public:
protected:
friend class Breakpoint;
RegularExpression m_regex; // This is the line expression that we are looking for.
bool m_exact_match;
private:
DISALLOW_COPY_AND_ASSIGN(BreakpointResolverFileRegex);

View File

@ -64,6 +64,9 @@ public:
void
SetDefaultArchitecture (const ArchSpec& arch);
bool
GetMoveToNearestCode () const;
lldb::DynamicValueType
GetPreferDynamicValue() const;
@ -701,7 +704,8 @@ public:
LazyBool check_inlines,
LazyBool skip_prologue,
bool internal,
bool request_hardware);
bool request_hardware,
LazyBool move_to_nearest_code);
// Use this to create breakpoint that matches regex against the source lines in files given in source_file_list:
lldb::BreakpointSP
@ -709,7 +713,8 @@ public:
const FileSpecList *source_file_list,
RegularExpression &source_regex,
bool internal,
bool request_hardware);
bool request_hardware,
LazyBool move_to_nearest_code);
// Use this to create a breakpoint from a load address
lldb::BreakpointSP

View File

@ -808,7 +808,8 @@ SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec,
const LazyBool skip_prologue = eLazyBoolCalculate;
const bool internal = false;
const bool hardware = false;
*sb_bp = target_sp->CreateBreakpoint (NULL, *sb_file_spec, line, check_inlines, skip_prologue, internal, hardware);
const LazyBool move_to_nearest_code = eLazyBoolCalculate;
*sb_bp = target_sp->CreateBreakpoint (NULL, *sb_file_spec, line, check_inlines, skip_prologue, internal, hardware, move_to_nearest_code);
}
if (log)
@ -1055,6 +1056,7 @@ SBTarget::BreakpointCreateBySourceRegex (const char *source_regex,
RegularExpression regexp(source_regex);
FileSpecList source_file_spec_list;
const bool hardware = false;
const LazyBool move_to_nearest_code = eLazyBoolCalculate;
source_file_spec_list.Append (source_file.ref());
if (module_name && module_name[0])
@ -1062,11 +1064,11 @@ SBTarget::BreakpointCreateBySourceRegex (const char *source_regex,
FileSpecList module_spec_list;
module_spec_list.Append (FileSpec (module_name, false));
*sb_bp = target_sp->CreateSourceRegexBreakpoint (&module_spec_list, &source_file_spec_list, regexp, false, hardware);
*sb_bp = target_sp->CreateSourceRegexBreakpoint (&module_spec_list, &source_file_spec_list, regexp, false, hardware, move_to_nearest_code);
}
else
{
*sb_bp = target_sp->CreateSourceRegexBreakpoint (NULL, &source_file_spec_list, regexp, false, hardware);
*sb_bp = target_sp->CreateSourceRegexBreakpoint (NULL, &source_file_spec_list, regexp, false, hardware, move_to_nearest_code);
}
}
@ -1095,8 +1097,9 @@ SBTarget::BreakpointCreateBySourceRegex (const char *source_regex,
{
Mutex::Locker api_locker (target_sp->GetAPIMutex());
const bool hardware = false;
const LazyBool move_to_nearest_code = eLazyBoolCalculate;
RegularExpression regexp(source_regex);
*sb_bp = target_sp->CreateSourceRegexBreakpoint (module_list.get(), source_file_list.get(), regexp, false, hardware);
*sb_bp = target_sp->CreateSourceRegexBreakpoint (module_list.get(), source_file_list.get(), regexp, false, hardware, move_to_nearest_code);
}
if (log)

View File

@ -32,13 +32,15 @@ BreakpointResolverFileLine::BreakpointResolverFileLine
const FileSpec &file_spec,
uint32_t line_no,
bool check_inlines,
bool skip_prologue
bool skip_prologue,
bool exact_match
) :
BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver),
m_file_spec (file_spec),
m_line_number (line_no),
m_inlines (check_inlines),
m_skip_prologue(skip_prologue)
m_skip_prologue(skip_prologue),
m_exact_match(exact_match)
{
}
@ -78,7 +80,7 @@ BreakpointResolverFileLine::SearchCallback
if (cu_sp)
{
if (filter.CompUnitPasses(*cu_sp))
cu_sp->ResolveSymbolContext (m_file_spec, m_line_number, m_inlines, false, eSymbolContextEverything, sc_list);
cu_sp->ResolveSymbolContext (m_file_spec, m_line_number, m_inlines, m_exact_match, eSymbolContextEverything, sc_list);
}
}
StreamString s;
@ -100,7 +102,7 @@ BreakpointResolverFileLine::GetDepth()
void
BreakpointResolverFileLine::GetDescription (Stream *s)
{
s->Printf ("file = '%s', line = %u", m_file_spec.GetPath().c_str(), m_line_number);
s->Printf ("file = '%s', line = %u, exact_match = %d", m_file_spec.GetPath().c_str(), m_line_number, m_exact_match);
}
void
@ -116,7 +118,8 @@ BreakpointResolverFileLine::CopyForBreakpoint (Breakpoint &breakpoint)
m_file_spec,
m_line_number,
m_inlines,
m_skip_prologue));
m_skip_prologue,
m_exact_match));
return ret_sp;
}

View File

@ -29,10 +29,12 @@ using namespace lldb_private;
BreakpointResolverFileRegex::BreakpointResolverFileRegex
(
Breakpoint *bkpt,
RegularExpression &regex
RegularExpression &regex,
bool exact_match
) :
BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver),
m_regex (regex)
m_regex (regex),
m_exact_match (exact_match)
{
}
@ -64,9 +66,8 @@ BreakpointResolverFileRegex::SearchCallback
{
SymbolContextList sc_list;
const bool search_inlines = false;
const bool exact = false;
cu->ResolveSymbolContext (cu_file_spec, line_matches[i], search_inlines, exact, eSymbolContextEverything, sc_list);
cu->ResolveSymbolContext (cu_file_spec, line_matches[i], search_inlines, m_exact_match, eSymbolContextEverything, sc_list);
const bool skip_prologue = true;
BreakpointResolver::SetSCMatchesByLine (filter, sc_list, skip_prologue, m_regex.GetText());
@ -85,7 +86,7 @@ BreakpointResolverFileRegex::GetDepth()
void
BreakpointResolverFileRegex::GetDescription (Stream *s)
{
s->Printf ("source regex = \"%s\"", m_regex.GetText());
s->Printf ("source regex = \"%s\", exact_match = %d", m_regex.GetText(), m_exact_match);
}
void
@ -97,7 +98,7 @@ BreakpointResolverFileRegex::Dump (Stream *s) const
lldb::BreakpointResolverSP
BreakpointResolverFileRegex::CopyForBreakpoint (Breakpoint &breakpoint)
{
lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileRegex(&breakpoint, m_regex));
lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileRegex(&breakpoint, m_regex, m_exact_match));
return ret_sp;
}

View File

@ -115,7 +115,8 @@ public:
m_exception_language (eLanguageTypeUnknown),
m_skip_prologue (eLazyBoolCalculate),
m_one_shot (false),
m_all_files (false)
m_all_files (false),
m_move_to_nearest_code (eLazyBoolCalculate)
{
}
@ -249,6 +250,22 @@ public:
error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg);
break;
}
case 'm':
{
bool success;
bool value;
value = Args::StringToBoolean (option_arg, true, &success);
if (value)
m_move_to_nearest_code = eLazyBoolYes;
else
m_move_to_nearest_code = eLazyBoolNo;
if (!success)
error.SetErrorStringWithFormat ("Invalid boolean value for move-to-nearest-code option: '%s'", option_arg);
break;
}
case 'M':
m_func_names.push_back (option_arg);
m_func_name_type_mask |= eFunctionNameTypeMethod;
@ -361,6 +378,7 @@ public:
m_breakpoint_names.clear();
m_all_files = false;
m_exception_extra_args.Clear();
m_move_to_nearest_code = eLazyBoolCalculate;
}
const OptionDefinition*
@ -400,6 +418,7 @@ public:
bool m_use_dummy;
bool m_all_files;
Args m_exception_extra_args;
LazyBool m_move_to_nearest_code;
};
@ -477,7 +496,8 @@ protected:
check_inlines,
m_options.m_skip_prologue,
internal,
m_options.m_hardware).get();
m_options.m_hardware,
m_options.m_move_to_nearest_code).get();
}
break;
@ -558,7 +578,8 @@ protected:
&(m_options.m_filenames),
regexp,
internal,
m_options.m_hardware).get();
m_options.m_hardware,
m_options.m_move_to_nearest_code).get();
}
break;
case eSetTypeException:
@ -689,6 +710,7 @@ private:
#define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
#define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
#define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
#define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 )
OptionDefinition
CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
@ -789,6 +811,9 @@ CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
{ LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
"Adds this to the list of names for this breakopint."},
{ LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
"Move breakpoints to nearest code. If not set the target.move-to-nearest-code setting is used." },
{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};

View File

@ -5326,7 +5326,8 @@ public:
eLazyBoolCalculate, // Check inlines using global setting
eLazyBoolCalculate, // Skip prologue using global setting,
false, // internal
false); // request_hardware
false, // request_hardware
eLazyBoolCalculate); // move_to_nearest_code
// Make breakpoint one shot
bp_sp->GetOptions()->SetOneShot(true);
exe_ctx.GetProcessRef().Resume();
@ -5361,7 +5362,8 @@ public:
eLazyBoolCalculate, // Check inlines using global setting
eLazyBoolCalculate, // Skip prologue using global setting,
false, // internal
false); // request_hardware
false, // request_hardware
eLazyBoolCalculate); // move_to_nearest_code
}
}
else if (m_selected_line < GetNumDisassemblyLines())

View File

@ -273,10 +273,13 @@ Target::CreateSourceRegexBreakpoint (const FileSpecList *containingModules,
const FileSpecList *source_file_spec_list,
RegularExpression &source_regex,
bool internal,
bool hardware)
bool hardware,
LazyBool move_to_nearest_code)
{
SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, source_file_spec_list));
BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex (NULL, source_regex));
if (move_to_nearest_code == eLazyBoolCalculate)
move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex (NULL, source_regex, !static_cast<bool>(move_to_nearest_code)));
return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
}
@ -288,7 +291,8 @@ Target::CreateBreakpoint (const FileSpecList *containingModules,
LazyBool check_inlines,
LazyBool skip_prologue,
bool internal,
bool hardware)
bool hardware,
LazyBool move_to_nearest_code)
{
if (check_inlines == eLazyBoolCalculate)
{
@ -325,12 +329,15 @@ Target::CreateBreakpoint (const FileSpecList *containingModules,
}
if (skip_prologue == eLazyBoolCalculate)
skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
if (move_to_nearest_code == eLazyBoolCalculate)
move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine (NULL,
file,
line_no,
check_inlines,
skip_prologue));
skip_prologue,
!static_cast<bool>(move_to_nearest_code)));
return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
}
@ -2928,6 +2935,7 @@ static PropertyDefinition
g_properties[] =
{
{ "default-arch" , OptionValue::eTypeArch , true , 0 , NULL, NULL, "Default architecture to choose, when there's a choice." },
{ "move-to-nearest-code" , OptionValue::eTypeBoolean , false, true , NULL, NULL, "Move breakpoints to nearest code." },
{ "expr-prefix" , OptionValue::eTypeFileSpec , false, 0 , NULL, NULL, "Path to a file containing expressions to be prepended to all expressions." },
{ "prefer-dynamic-value" , OptionValue::eTypeEnum , false, eDynamicDontRunTarget , NULL, g_dynamic_value_types, "Should printed values be shown as their dynamic value." },
{ "enable-synthetic-value" , OptionValue::eTypeBoolean , false, true , NULL, NULL, "Should synthetic values be used by default whenever available." },
@ -2985,6 +2993,7 @@ g_properties[] =
enum
{
ePropertyDefaultArch,
ePropertyMoveToNearestCode,
ePropertyExprPrefix,
ePropertyPreferDynamic,
ePropertyEnableSynthetic,
@ -3193,6 +3202,13 @@ TargetProperties::SetDefaultArchitecture (const ArchSpec& arch)
return value->SetCurrentValue(arch, true);
}
bool
TargetProperties::GetMoveToNearestCode() const
{
const uint32_t idx = ePropertyMoveToNearestCode;
return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
}
lldb::DynamicValueType
TargetProperties::GetPreferDynamicValue() const
{

View File

@ -64,12 +64,12 @@ class BreakpointCommandTestCase(TestBase):
# The breakpoint list now only contains breakpoint 1.
self.expect("breakpoint list", "Breakpoints 1 & 2 created",
substrs = ["2: file = 'main.c', line = %d, locations = 1" % self.line],
patterns = ["1: file = '.*main.c', line = %d, locations = 1" % self.line] )
substrs = ["2: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line],
patterns = ["1: file = '.*main.c', line = %d, exact_match = 0, locations = 1" % self.line] )
self.expect("breakpoint list -f", "Breakpoints 1 & 2 created",
substrs = ["2: file = 'main.c', line = %d, locations = 1" % self.line],
patterns = ["1: file = '.*main.c', line = %d, locations = 1" % self.line,
substrs = ["2: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line],
patterns = ["1: file = '.*main.c', line = %d, exact_match = 0, locations = 1" % self.line,
"1.1: .+at main.c:%d, .+unresolved, hit count = 0" % self.line,
"2.1: .+at main.c:%d, .+unresolved, hit count = 0" % self.line])
@ -151,13 +151,13 @@ class BreakpointCommandTestCase(TestBase):
# The breakpoint list now only contains breakpoint 1.
self.expect("breakpoint list -f", "Breakpoint 1 exists",
patterns = ["1: file = '.*main.c', line = %d, locations = 1, resolved = 1" %
patterns = ["1: file = '.*main.c', line = %d, exact_match = 0, locations = 1, resolved = 1" %
self.line,
"hit count = 1"])
# Not breakpoint 2.
self.expect("breakpoint list -f", "No more breakpoint 2", matching=False,
substrs = ["2: file = 'main.c', line = %d, locations = 1, resolved = 1" %
substrs = ["2: file = 'main.c', line = %d, exact_match = 0, locations = 1, resolved = 1" %
self.line])
# Run the program again, with breakpoint 1 remaining.

View File

@ -41,7 +41,7 @@ class BreakpointLocationsTestCase(TestBase):
# The breakpoint list should show 3 locations.
self.expect("breakpoint list -f", "Breakpoint locations shown correctly",
substrs = ["1: file = 'main.c', line = %d, locations = 3" % self.line],
substrs = ["1: file = 'main.c', line = %d, exact_match = 0, locations = 3" % self.line],
patterns = ["where = a.out`func_inlined .+unresolved, hit count = 0",
"where = a.out`main .+\[inlined\].+unresolved, hit count = 0"])

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,77 @@
"""
Test breakpoint command for different options.
"""
import os
import unittest2
import lldb
from lldbtest import *
import lldbutil
class BreakpointOptionsTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipUnlessDarwin
@dsym_test
def test_with_dsym(self):
"""Test breakpoint command for different options."""
self.buildDsym()
self.breakpoint_options_test()
@dwarf_test
def test_with_dwarf(self):
"""Test breakpoint command for different options."""
self.buildDwarf()
self.breakpoint_options_test()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number('main.c', '// Set break point at this line.')
def breakpoint_options_test(self):
"""Test breakpoint command for different options."""
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# This should create a breakpoint with 1 locations.
lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, extra_options = "-K 1", num_expected_locations = 1)
lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, extra_options = "-K 0", num_expected_locations = 1)
# This should create a breakpoint 0 locations.
lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, extra_options = "-m 0", num_expected_locations = 0)
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)
# Stopped once.
self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
substrs = ["stop reason = breakpoint 2."])
# Check the list of breakpoint.
self.expect("breakpoint list -f", "Breakpoint locations shown correctly",
substrs = ["1: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line,
"2: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line,
"3: file = 'main.c', line = %d, exact_match = 1, locations = 0" % self.line])
# Continue the program, there should be another stop.
self.runCmd("process continue")
# Stopped again.
self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
substrs = ["stop reason = breakpoint 1."])
# Continue the program, we should exit.
self.runCmd("process continue")
# We should exit.
self.expect("process status", "Process exited successfully",
patterns = ["^Process [0-9]+ exited with status = 0"])
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@ -0,0 +1,7 @@
// Set break point at this line.
int
main (int argc, char **argv)
{
return 0;
}

View File

@ -54,8 +54,8 @@ class BreakpointInDummyTarget (TestBase):
# The breakpoint list should show 3 locations.
self.expect("breakpoint list -f", "Breakpoint locations shown correctly",
substrs = ["1: file = 'main.c', line = %d, locations = 1" % self.line,
"2: file = 'main.c', line = %d, locations = 1" % self.line2])
substrs = ["1: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line,
"2: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line2])
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)

View File

@ -41,7 +41,7 @@ class NumberOfThreadsTestCase(TestBase):
# The breakpoint list should show 3 locations.
self.expect("breakpoint list -f", "Breakpoint location shown correctly",
substrs = ["1: file = 'main.c', line = %d, locations = 1" % self.line])
substrs = ["1: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line])
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)

View File

@ -106,7 +106,7 @@ class ExitDuringStepTestCase(TestBase):
# The breakpoint list should show 1 location.
self.expect("breakpoint list -f", "Breakpoint location shown correctly",
substrs = ["1: file = 'main.cpp', line = %d, locations = 1" % self.breakpoint])
substrs = ["1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.breakpoint])
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)

View File

@ -143,7 +143,7 @@ class ThreadStateTestCase(TestBase):
# The breakpoint list should show 1 breakpoints with 1 location.
self.expect("breakpoint list -f", "Breakpoint location shown correctly",
substrs = ["1: file = 'main.c', line = %d, locations = 1" % self.break_1])
substrs = ["1: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.break_1])
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)

View File

@ -110,7 +110,7 @@ class ThreadStepOutTestCase(TestBase):
# The breakpoint list should show 1 location.
self.expect("breakpoint list -f", "Breakpoint location shown correctly",
substrs = ["1: file = 'main.cpp', line = %d, locations = 1" % self.breakpoint])
substrs = ["1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.breakpoint])
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)

View File

@ -466,7 +466,7 @@ def check_breakpoint_result (test, break_results, file_name=None, line_number=-1
test.assertTrue (file_name == out_file_name, "Breakpoint file name '%s' doesn't match resultant name '%s'."%(file_name, out_file_name))
if line_number != -1:
out_file_line = -1
out_line_number = -1
if 'line_no' in break_results:
out_line_number = break_results['line_no']
@ -486,7 +486,7 @@ def check_breakpoint_result (test, break_results, file_name=None, line_number=-1
test.assertTrue(out_symbol_name.find(symbol_name) != -1, "Symbol name '%s' isn't in resultant symbol '%s'."%(symbol_name, out_symbol_name))
if module_name:
out_nodule_name = None
out_module_name = None
if 'module' in break_results:
out_module_name = break_results['module']

View File

@ -450,6 +450,7 @@ class SettingsCommandTestCase(TestBase):
"thread-format",
"use-external-editor",
"target.default-arch",
"target.move-to-nearest-code",
"target.expr-prefix",
"target.prefer-dynamic-value",
"target.enable-synthetic-value",

View File

@ -159,5 +159,52 @@ class MiBreakTestCase(lldbmi_testcase.MiTestCaseBase):
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\"")
@lldbmi_test
@expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_break_insert_settings(self):
"""Test that 'lldb-mi --interpreter' can set breakpoints accoridng to global options."""
self.spawnLldbMi(args = None)
# Load executable
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
self.expect("\^done")
# Set target.move-to-nearest-code=off and try to set BP #1 that shouldn't be hit
self.runCmd("-interpreter-exec console \"settings set target.move-to-nearest-code off\"")
self.expect("\^done")
line = line_number('main.cpp', '// BP_before_main')
self.runCmd("-break-insert -f main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"1\"")
# Set target.move-to-nearest-code=on and target.skip-prologue=on and set BP #2
self.runCmd("-interpreter-exec console \"settings set target.move-to-nearest-code on\"")
self.runCmd("-interpreter-exec console \"settings set target.skip-prologue on\"")
self.expect("\^done")
self.runCmd("-break-insert main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"2\"")
# Set target.skip-prologue=off and set BP #3
self.runCmd("-interpreter-exec console \"settings set target.skip-prologue off\"")
self.expect("\^done")
self.runCmd("-break-insert main.cpp:%d" % line)
self.expect("\^done,bkpt={number=\"3\"")
# Test that BP #3 is located before BP #2
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"3\"")
# Test that BP #2 is hit
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"2\"")
# Test that BP #1 wasn't set
self.runCmd("-exec-continue")
self.expect("\^running")
self.expect("\*stopped,reason=\"exited-normally\"")
if __name__ == '__main__':
unittest2.main()

View File

@ -9,6 +9,8 @@
#include <cstdio>
// BP_before_main
int
main(int argc, char const *argv[])
{