Skip to content

Commit 4c23625

Browse files
kendalharlandkendal
and
kendal
authored
Fix flake in TestZerothFrame.py (llvm#96685)
This test is currently flaky on a local Windows amd64 build. The reason is that it relies on the order of `process.threads` but this order is nondeterministic: If we print lldb's inputs and outputs while running, we can see that the breakpoints are always being set correctly, and always being hit: ```sh runCmd: breakpoint set -f "main.c" -l 2 output: Breakpoint 1: where = a.out`func_inner + 1 at main.c:2:9, address = 0x0000000140001001 runCmd: breakpoint set -f "main.c" -l 7 output: Breakpoint 2: where = a.out`main + 17 at main.c:7:5, address = 0x0000000140001021 runCmd: run output: Process 52328 launched: 'C:\workspace\llvm-project\llvm\build\lldb-test-build.noindex\functionalities\unwind\zeroth_frame\TestZerothFrame.test_dwarf\a.out' (x86_64) Process 52328 stopped * thread #1, stop reason = breakpoint 1.1 frame #0: 0x00007ff68f6b1001 a.out`func_inner at main.c:2:9 1 void func_inner() { -> 2 int a = 1; // Set breakpoint 1 here ^ 3 } 4 5 int main() { 6 func_inner(); 7 return 0; // Set breakpoint 2 here ``` However, sometimes the backtrace printed in this test shows that the process is stopped inside NtWaitForWorkViaWorkerFactory from `ntdll.dll`: ```sh Backtrace at the first breakpoint: frame #0: 0x00007ffecc7b3bf4 ntdll.dll`NtWaitForWorkViaWorkerFactory + 20 frame #1: 0x00007ffecc74585e ntdll.dll`RtlClearThreadWorkOnBehalfTicket + 862 frame #2: 0x00007ffecc3e257d kernel32.dll`BaseThreadInitThunk + 29 frame #3: 0x00007ffecc76af28 ntdll.dll`RtlUserThreadStart + 40 ``` When this happens, the test fails with an assertion error that the stopped thread's zeroth frame's current line number does not match the expected line number. This is because the test is looking at the wrong thread: `process.threads[0]`. If we print the list of threads each time the test is run, we notice that threads are sometimes in a different order, within `process.threads`: ```sh Thread 0: thread #4: tid = 0x9c38, 0x00007ffecc7b3bf4 ntdll.dll`NtWaitForWorkViaWorkerFactory + 20 Thread 1: thread #2: tid = 0xa950, 0x00007ffecc7b3bf4 ntdll.dll`NtWaitForWorkViaWorkerFactory + 20 Thread 2: thread #1: tid = 0xab18, 0x00007ff64bc81001 a.out`func_inner at main.c:2:9, stop reason = breakpoint 1.1 Thread 3: thread #3: tid = 0xc514, 0x00007ffecc7b3bf4 ntdll.dll`NtWaitForWorkViaWorkerFactory + 20 Thread 0: thread #3: tid = 0x018c, 0x00007ffecc7b3bf4 ntdll.dll`NtWaitForWorkViaWorkerFactory + 20 Thread 1: thread #1: tid = 0x85c8, 0x00007ff7130c1001 a.out`func_inner at main.c:2:9, stop reason = breakpoint 1.1 Thread 2: thread #2: tid = 0xf344, 0x00007ffecc7b3bf4 ntdll.dll`NtWaitForWorkViaWorkerFactory + 20 Thread 3: thread #4: tid = 0x6a50, 0x00007ffecc7b3bf4 ntdll.dll`NtWaitForWorkViaWorkerFactory + 20 ``` Use `self.thread()` to consistently select the correct thread, instead. Co-authored-by: kendal <[email protected]>
1 parent c2fe75f commit 4c23625

File tree

1 file changed

+11
-12
lines changed

1 file changed

+11
-12
lines changed

lldb/test/API/functionalities/unwind/zeroth_frame/TestZerothFrame.py

+11-12
Original file line numberDiff line numberDiff line change
@@ -40,28 +40,28 @@ def test(self):
4040
target = self.dbg.CreateTarget(exe)
4141
self.assertTrue(target, VALID_TARGET)
4242

43-
bp1_line = line_number("main.c", "// Set breakpoint 1 here")
44-
bp2_line = line_number("main.c", "// Set breakpoint 2 here")
45-
46-
lldbutil.run_break_set_by_file_and_line(
47-
self, "main.c", bp1_line, num_expected_locations=1
43+
main_dot_c = lldb.SBFileSpec("main.c")
44+
bp1 = target.BreakpointCreateBySourceRegex(
45+
"// Set breakpoint 1 here", main_dot_c
4846
)
49-
lldbutil.run_break_set_by_file_and_line(
50-
self, "main.c", bp2_line, num_expected_locations=1
47+
bp2 = target.BreakpointCreateBySourceRegex(
48+
"// Set breakpoint 2 here", main_dot_c
5149
)
5250

5351
process = target.LaunchSimple(None, None, self.get_process_working_directory())
5452
self.assertTrue(process, VALID_PROCESS)
5553

56-
thread = process.GetThreadAtIndex(0)
54+
thread = self.thread()
55+
5756
if self.TraceOn():
5857
print("Backtrace at the first breakpoint:")
5958
for f in thread.frames:
6059
print(f)
60+
6161
# Check that we have stopped at correct breakpoint.
6262
self.assertEqual(
63-
process.GetThreadAtIndex(0).frame[0].GetLineEntry().GetLine(),
64-
bp1_line,
63+
thread.frame[0].GetLineEntry().GetLine(),
64+
bp1.GetLocationAtIndex(0).GetAddress().GetLineEntry().GetLine(),
6565
"LLDB reported incorrect line number.",
6666
)
6767

@@ -70,15 +70,14 @@ def test(self):
7070
# 'continue' command.
7171
process.Continue()
7272

73-
thread = process.GetThreadAtIndex(0)
7473
if self.TraceOn():
7574
print("Backtrace at the second breakpoint:")
7675
for f in thread.frames:
7776
print(f)
7877
# Check that we have stopped at the breakpoint
7978
self.assertEqual(
8079
thread.frame[0].GetLineEntry().GetLine(),
81-
bp2_line,
80+
bp2.GetLocationAtIndex(0).GetAddress().GetLineEntry().GetLine(),
8281
"LLDB reported incorrect line number.",
8382
)
8483
# Double-check with GetPCAddress()

0 commit comments

Comments
 (0)