Skip to content

Commit 56ec13a

Browse files
jiminghammedismailben
authored andcommitted
Fix a bug with setting breakpoints on C++11 inline initialization statements.
If they occurred before the constructor that used them, we would refuse to set the breakpoint because we thought they were crossing function boundaries. Differential Revision: https://reviews.llvm.org/D94846
1 parent 82846cf commit 56ec13a

File tree

4 files changed

+95
-0
lines changed

4 files changed

+95
-0
lines changed

lldb/source/Breakpoint/BreakpointResolverFileLine.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,14 @@ void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list,
187187
// is 0, then we can't do this calculation. That can happen if
188188
// GetStartLineSourceInfo gets an error, or if the first line number in
189189
// the function really is 0 - which happens for some languages.
190+
191+
// But only do this calculation if the line number we found in the SC
192+
// was different from the one requested in the source file. If we actually
193+
// found an exact match it must be valid.
194+
195+
if (m_line_number == sc.line_entry.line)
196+
continue;
197+
190198
const int decl_line_is_too_late_fudge = 1;
191199
if (line && m_line_number < line - decl_line_is_too_late_fudge) {
192200
LLDB_LOG(log, "removing symbol context at {0}:{1}", file, line);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
C_SOURCES := main.c
2+
CXXFLAGS_EXTRAS := -std=c++11
3+
4+
include Makefile.rules
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"""
2+
When using C++11 in place member initialization, show that we
3+
can set and hit breakpoints on initialization lines. This is a
4+
little bit tricky because we try not to move file and line breakpoints
5+
across function boundaries but these lines are outside the source range
6+
of the constructor.
7+
"""
8+
9+
10+
11+
import lldb
12+
import lldbsuite.test.lldbutil as lldbutil
13+
from lldbsuite.test.lldbtest import *
14+
15+
16+
class RenameThisSampleTestTestCase(TestBase):
17+
18+
mydir = TestBase.compute_mydir(__file__)
19+
20+
def test_breakpoints_on_initializers(self):
21+
"""Show we can set breakpoints on initializers appearing both before
22+
and after the constructor body, and hit them."""
23+
self.build()
24+
self.main_source_file = lldb.SBFileSpec("main.cpp")
25+
self.first_initializer_line = line_number("main.cpp", "Set the before constructor breakpoint here")
26+
self.second_initializer_line = line_number("main.cpp", "Set the after constructor breakpoint here")
27+
self.sample_test()
28+
29+
def setUp(self):
30+
# Call super's setUp().
31+
TestBase.setUp(self)
32+
# Set up your test case here. If your test doesn't need any set up then
33+
# remove this method from your TestCase class.
34+
35+
def sample_test(self):
36+
"""You might use the test implementation in several ways, say so here."""
37+
38+
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
39+
" Set a breakpoint here to get started", self.main_source_file)
40+
41+
# Now set breakpoints on the two initializer lines we found in the test startup:
42+
bkpt1 = target.BreakpointCreateByLocation(self.main_source_file, self.first_initializer_line)
43+
self.assertEqual(bkpt1.GetNumLocations(), 1)
44+
bkpt2 = target.BreakpointCreateByLocation(self.main_source_file, self.second_initializer_line)
45+
self.assertEqual(bkpt2.GetNumLocations(), 1)
46+
47+
# Now continue, we should stop at the two breakpoints above, first the one before, then
48+
# the one after.
49+
self.assertEqual(len(lldbutil.continue_to_breakpoint(process, bkpt1)), 1, "Hit first breakpoint")
50+
self.assertEqual(len(lldbutil.continue_to_breakpoint(process, bkpt2)), 1, "Hit second breakpoint")
51+
52+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <stdio.h>
2+
#include <vector>
3+
4+
class Trivial {
5+
public:
6+
Trivial(int input) : m_int(input) {}
7+
private:
8+
int m_int;
9+
10+
};
11+
12+
class Foo {
13+
private:
14+
Trivial m_trivial = Trivial(100); // Set the before constructor breakpoint here
15+
16+
public:
17+
Foo(int input) {
18+
printf("I have been made!\n");
19+
}
20+
21+
private:
22+
Trivial m_other_trivial = Trivial(200); // Set the after constructor breakpoint here
23+
};
24+
25+
int
26+
main()
27+
{
28+
Foo myFoo(10); // Set a breakpoint here to get started
29+
return 0;
30+
}
31+

0 commit comments

Comments
 (0)