[Lldb-commits] [lldb] r258586 - More fixes related to counting threads on Windows.

Zachary Turner via lldb-commits lldb-commits at lists.llvm.org
Fri Jan 22 16:13:41 PST 2016


By the way, I'm reminded of a discussion we had on an old bug report where
we said that an even better way to do this would be to name threads from
inside the debugger and have the test fetch threads with specific names.
That's probably still a better way to do this (especially when multiple
threads are involved as opposed to just the main thread)

On Fri, Jan 22, 2016 at 4:10 PM Zachary Turner <zturner at google.com> wrote:

> Yea, that's a good idea.  Thanks for the suggestion
>
> On Fri, Jan 22, 2016 at 4:05 PM Jim Ingham <jingham at apple.com> wrote:
>
>> Would you mind adding a comment telling people how to do this correctly
>> to the "Writing test cases" section of the README-testsuite?
>>
>> Jim
>>
>> > On Jan 22, 2016, at 3:54 PM, Zachary Turner via lldb-commits <
>> lldb-commits at lists.llvm.org> wrote:
>> >
>> > Author: zturner
>> > Date: Fri Jan 22 17:54:41 2016
>> > New Revision: 258586
>> >
>> > URL: http://llvm.org/viewvc/llvm-project?rev=258586&view=rev
>> > Log:
>> > More fixes related to counting threads on Windows.
>> >
>> > The Windows 10 loader spawns threads at startup, so
>> > tests which count threads or assume that a given user
>> > thread will be at a specific index are incorrect in
>> > this case.  The fix here is to use the standard mechanisms
>> > for getting the stopped thread (which is all we are
>> > really interested in anyway) and correlating them with
>> > the breakpoints that were set, and doing checks against
>> > those things.
>> >
>> > This fixes about 6 tests on Windows 10.
>> >
>> > Modified:
>> >
>> lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py
>> >
>> lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py
>> >    lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py
>> >
>> > Modified:
>> lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py
>> > URL:
>> http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py?rev=258586&r1=258585&r2=258586&view=diff
>> >
>> ==============================================================================
>> > ---
>> lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py
>> (original)
>> > +++
>> lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py
>> Fri Jan 22 17:54:41 2016
>> > @@ -18,14 +18,12 @@ class ExitDuringStepTestCase(TestBase):
>> >     @expectedFailureDarwin("llvm.org/pr15824") # thread states not
>> properly maintained
>> >     @expectedFailureFreeBSD("llvm.org/pr18190") # thread states not
>> properly maintained
>> >     @expectedFailureLinux("llvm.org/pr15824") # thread states not
>> properly maintained
>> > -    @expectedFailureWindows("llvm.org/pr24681")
>> >     def test_thread_state_is_stopped(self):
>> >         """Test thread exit during step handling."""
>> >         self.build(dictionary=self.getBuildFlags())
>> >         self.exit_during_step_base("thread step-in -m all-threads",
>> 'stop reason = step in', True)
>> >
>> >     @skipIfFreeBSD # llvm.org/pr21411: test is hanging
>> > -    @expectedFailureWindows("llvm.org/pr24681")
>> >     @expectedFlakeyAndroid("llvm.org/pr26206")
>> >     def test(self):
>> >         """Test thread exit during step handling."""
>> > @@ -33,7 +31,6 @@ class ExitDuringStepTestCase(TestBase):
>> >         self.exit_during_step_base("thread step-inst -m all-threads",
>> 'stop reason = instruction step', False)
>> >
>> >     @skipIfFreeBSD # llvm.org/pr21411: test is hanging
>> > -    @expectedFailureWindows("llvm.org/pr24681")
>> >     @expectedFlakeyAndroid("llvm.org/pr26206")
>> >     def test_step_over(self):
>> >         """Test thread exit during step-over handling."""
>> > @@ -41,7 +38,6 @@ class ExitDuringStepTestCase(TestBase):
>> >         self.exit_during_step_base("thread step-over -m all-threads",
>> 'stop reason = step over', False)
>> >
>> >     @skipIfFreeBSD # llvm.org/pr21411: test is hanging
>> > -    @expectedFailureWindows("llvm.org/pr24681")
>> >     @expectedFlakeyAndroid("llvm.org/pr26206")
>> >     def test_step_in(self):
>> >         """Test thread exit during step-in handling."""
>> > @@ -79,37 +75,16 @@ class ExitDuringStepTestCase(TestBase):
>> >         target = self.dbg.GetSelectedTarget()
>> >         process = target.GetProcess()
>> >
>> > -        # Get the number of threads
>> >         num_threads = process.GetNumThreads()
>> > -
>> >         # Make sure we see all three threads
>> > -        self.assertTrue(num_threads == 3, 'Number of expected threads
>> and actual threads do not match.')
>> > +        self.assertGreaterEqual(num_threads, 3, 'Number of expected
>> threads and actual threads do not match.')
>> >
>> > -        # Get the thread objects
>> > -        thread1 = process.GetThreadAtIndex(0)
>> > -        thread2 = process.GetThreadAtIndex(1)
>> > -        thread3 = process.GetThreadAtIndex(2)
>> > -
>> > -        # Make sure all threads are stopped
>> > -        if test_thread_state:
>> > -            self.assertTrue(thread1.IsStopped(), "Thread 1 didn't stop
>> during breakpoint")
>> > -            self.assertTrue(thread2.IsStopped(), "Thread 2 didn't stop
>> during breakpoint")
>> > -            self.assertTrue(thread3.IsStopped(), "Thread 3 didn't stop
>> during breakpoint")
>> > -            return
>> > -
>> > -        # Find the thread that is stopped at the breakpoint
>> > -        stepping_thread = None
>> > -        for thread in process:
>> > -            expected_bp_desc = "breakpoint %s." % self.bp_num
>> > -            stop_desc = thread.GetStopDescription(100)
>> > -            if stop_desc and (expected_bp_desc in stop_desc):
>> > -                stepping_thread = thread
>> > -                break
>> > -        self.assertTrue(stepping_thread != None, "unable to find
>> thread stopped at %s" % expected_bp_desc)
>> > +        stepping_thread =
>> lldbutil.get_one_thread_stopped_at_breakpoint_id(process, self.bp_num)
>> > +        self.assertIsNotNone(stepping_thread, "Could not find a thread
>> stopped at the breakpoint")
>> >
>> >         current_line = self.breakpoint
>> >         stepping_frame = stepping_thread.GetFrameAtIndex(0)
>> > -        self.assertTrue(current_line ==
>> stepping_frame.GetLineEntry().GetLine(), "Starting line for stepping
>> doesn't match breakpoint line.")
>> > +        self.assertEqual(current_line,
>> stepping_frame.GetLineEntry().GetLine(), "Starting line for stepping
>> doesn't match breakpoint line.")
>> >
>> >         # Keep stepping until we've reached our designated continue
>> point
>> >         while current_line != self.continuepoint:
>> > @@ -125,16 +100,16 @@ class ExitDuringStepTestCase(TestBase):
>> >
>> >             current_line = frame.GetLineEntry().GetLine()
>> >
>> > -            self.assertTrue(current_line >= self.breakpoint, "Stepped
>> to unexpected line, " + str(current_line))
>> > -            self.assertTrue(current_line <= self.continuepoint,
>> "Stepped to unexpected line, " + str(current_line))
>> > +            self.assertGreaterEqual(current_line, self.breakpoint,
>> "Stepped to unexpected line, " + str(current_line))
>> > +            self.assertLessEqual(current_line, self.continuepoint,
>> "Stepped to unexpected line, " + str(current_line))
>> >
>> >         self.runCmd("thread list")
>> >
>> >         # Update the number of threads
>> > -        num_threads = process.GetNumThreads()
>> > +        new_num_threads = process.GetNumThreads()
>> >
>> >         # Check to see that we reduced the number of threads as expected
>> > -        self.assertTrue(num_threads == 2, 'Number of expected threads
>> and actual threads do not match after thread exit.')
>> > +        self.assertEqual(new_num_threads, num_threads-1, 'Number of
>> threads did not reduce by 1 after thread exit.')
>> >
>> >         self.expect("thread list", 'Process state is stopped due to
>> step',
>> >                 substrs = ['stopped',
>> > @@ -144,4 +119,4 @@ class ExitDuringStepTestCase(TestBase):
>> >         self.runCmd("continue")
>> >
>> >         # At this point, the inferior process should have exited.
>> > -        self.assertTrue(process.GetState() == lldb.eStateExited,
>> PROCESS_EXITED)
>> > +        self.assertEqual(process.GetState(), lldb.eStateExited,
>> PROCESS_EXITED)
>> >
>> > Modified:
>> lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py
>> > URL:
>> http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py?rev=258586&r1=258585&r2=258586&view=diff
>> >
>> ==============================================================================
>> > ---
>> lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py
>> (original)
>> > +++
>> lldb/trunk/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py
>> Fri Jan 22 17:54:41 2016
>> > @@ -24,7 +24,6 @@ class ThreadExitTestCase(TestBase):
>> >         self.break_3 = line_number('main.cpp', '// Set third breakpoint
>> here')
>> >         self.break_4 = line_number('main.cpp', '// Set fourth
>> breakpoint here')
>> >
>> > -    @expectedFailureWindows("llvm.org/pr24681")
>> >     def test(self):
>> >         """Test thread exit handling."""
>> >         self.build(dictionary=self.getBuildFlags())
>> > @@ -32,10 +31,10 @@ class ThreadExitTestCase(TestBase):
>> >         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
>> >
>> >         # This should create a breakpoint with 1 location.
>> > -        lldbutil.run_break_set_by_file_and_line (self, "main.cpp",
>> self.break_1, num_expected_locations=1)
>> > -        lldbutil.run_break_set_by_file_and_line (self, "main.cpp",
>> self.break_2, num_expected_locations=1)
>> > -        lldbutil.run_break_set_by_file_and_line (self, "main.cpp",
>> self.break_3, num_expected_locations=1)
>> > -        lldbutil.run_break_set_by_file_and_line (self, "main.cpp",
>> self.break_4, num_expected_locations=1)
>> > +        bp1_id = lldbutil.run_break_set_by_file_and_line (self,
>> "main.cpp", self.break_1, num_expected_locations=1)
>> > +        bp2_id = lldbutil.run_break_set_by_file_and_line (self,
>> "main.cpp", self.break_2, num_expected_locations=1)
>> > +        bp3_id = lldbutil.run_break_set_by_file_and_line (self,
>> "main.cpp", self.break_3, num_expected_locations=1)
>> > +        bp4_id = lldbutil.run_break_set_by_file_and_line (self,
>> "main.cpp", self.break_4, num_expected_locations=1)
>> >
>> >         # The breakpoint list should show 1 locations.
>> >         self.expect("breakpoint list -f", "Breakpoint location shown
>> correctly",
>> > @@ -46,71 +45,46 @@ class ThreadExitTestCase(TestBase):
>> >
>> >         # Run the program.
>> >         self.runCmd("run", RUN_SUCCEEDED)
>> > -
>> > -        # The stop reason of the thread should be breakpoint 1.
>> > -        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 1",
>> > -            substrs = ['stopped',
>> > -                       '* thread #1',
>> > -                       'stop reason = breakpoint 1',
>> > -                       'thread #2'])
>> > -
>> >         # Get the target process
>> >         target = self.dbg.GetSelectedTarget()
>> >         process = target.GetProcess()
>> >
>> > +        stopped_thread =
>> lldbutil.get_one_thread_stopped_at_breakpoint_id(process, bp1_id)
>> > +        self.assertIsNotNone(stopped_thread, "Process is not stopped
>> at breakpoint 1")
>> > +
>> >         # Get the number of threads
>> >         num_threads = process.GetNumThreads()
>> > -
>> > -        self.assertTrue(num_threads == 2, 'Number of expected threads
>> and actual threads do not match at breakpoint 1.')
>> > +        self.assertGreaterEqual(num_threads, 2, 'Number of expected
>> threads and actual threads do not match at breakpoint 1.')
>> >
>> >         # Run to the second breakpoint
>> >         self.runCmd("continue")
>> > -
>> > -        # The stop reason of the thread should be breakpoint 1.
>> > -        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 2",
>> > -            substrs = ['stopped',
>> > -                       'thread #1',
>> > -                       'thread #2',
>> > -                       'stop reason = breakpoint 2',
>> > -                       'thread #3'])
>> > +        stopped_thread =
>> lldbutil.get_one_thread_stopped_at_breakpoint_id(process, bp2_id)
>> > +        self.assertIsNotNone(stopped_thread, "Process is not stopped
>> at breakpoint 2")
>> >
>> >         # Update the number of threads
>> > -        num_threads = process.GetNumThreads()
>> > -
>> > -        self.assertTrue(num_threads == 3, 'Number of expected threads
>> and actual threads do not match at breakpoint 2.')
>> > +        new_num_threads = process.GetNumThreads()
>> > +        self.assertEqual(new_num_threads, num_threads+1, 'Number of
>> expected threads did not increase by 1 at bp 2.')
>> >
>> >         # Run to the third breakpoint
>> >         self.runCmd("continue")
>> > -
>> > -        # The stop reason of the thread should be breakpoint 3.
>> > -        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 3",
>> > -            substrs = ['stopped',
>> > -                       'thread #1',
>> > -                       'stop reason = breakpoint 3',
>> > -                       'thread #3',
>> > -                       ])
>> > +        stopped_thread =
>> lldbutil.get_one_thread_stopped_at_breakpoint_id(process, bp3_id)
>> > +        self.assertIsNotNone(stopped_thread, "Process is not stopped
>> at breakpoint 3")
>> >
>> >         # Update the number of threads
>> > -        num_threads = process.GetNumThreads()
>> > -
>> > -        self.assertTrue(num_threads == 2, 'Number of expected threads
>> and actual threads do not match at breakpoint 3.')
>> > +        new_num_threads = process.GetNumThreads()
>> > +        self.assertEqual(new_num_threads, num_threads, 'Number of
>> expected threads is not equal to original number of threads at bp 3.')
>> >
>> >         # Run to the fourth breakpoint
>> >         self.runCmd("continue")
>> > -
>> > -        # The stop reason of the thread should be breakpoint 4.
>> > -        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 4",
>> > -            substrs = ['stopped',
>> > -                       'thread #1',
>> > -                       'stop reason = breakpoint 4'])
>> > +        stopped_thread =
>> lldbutil.get_one_thread_stopped_at_breakpoint_id(process, bp4_id)
>> > +        self.assertIsNotNone(stopped_thread, "Process is not stopped
>> at breakpoint 4")
>> >
>> >         # Update the number of threads
>> > -        num_threads = process.GetNumThreads()
>> > -
>> > -        self.assertTrue(num_threads == 1, 'Number of expected threads
>> and actual threads do not match at breakpoint 4.')
>> > +        new_num_threads = process.GetNumThreads()
>> > +        self.assertEqual(new_num_threads, num_threads-1, 'Number of
>> expected threads did not decrease by 1 at bp 4.')
>> >
>> >         # Run to completion
>> >         self.runCmd("continue")
>> >
>> >         # At this point, the inferior process should have exited.
>> > -        self.assertTrue(process.GetState() == lldb.eStateExited,
>> PROCESS_EXITED)
>> > +        self.assertEqual(process.GetState(), lldb.eStateExited,
>> PROCESS_EXITED)
>> >
>> > Modified: lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py
>> > URL:
>> http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py?rev=258586&r1=258585&r2=258586&view=diff
>> >
>> ==============================================================================
>> > --- lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py (original)
>> > +++ lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py Fri Jan 22
>> 17:54:41 2016
>> > @@ -548,7 +548,7 @@ def get_stopped_thread(process, reason):
>> >         return None
>> >     return threads[0]
>> >
>> > -def get_threads_stopped_at_breakpoint (process, bkpt):
>> > +def get_threads_stopped_at_breakpoint_id(process, bpid):
>> >     """ For a stopped process returns the thread stopped at the
>> breakpoint passed in bkpt"""
>> >     stopped_threads = []
>> >     threads = []
>> > @@ -561,13 +561,16 @@ def get_threads_stopped_at_breakpoint (p
>> >     for thread in stopped_threads:
>> >         # Make sure we've hit our breakpoint...
>> >         break_id = thread.GetStopReasonDataAtIndex (0)
>> > -        if break_id == bkpt.GetID():
>> > +        if break_id == bpid:
>> >             threads.append(thread)
>> >
>> >     return threads
>> >
>> > -def get_one_thread_stopped_at_breakpoint(process, bkpt,
>> require_exactly_one = True):
>> > -    threads = get_threads_stopped_at_breakpoint(process, bkpt)
>> > +def get_threads_stopped_at_breakpoint (process, bkpt):
>> > +    return get_threads_stopped_at_breakpoint_id(process, bkpt.GetID())
>> > +
>> > +def get_one_thread_stopped_at_breakpoint_id(process, bpid,
>> require_exactly_one = True):
>> > +    threads = get_threads_stopped_at_breakpoint_id(process, bpid)
>> >     if len(threads) == 0:
>> >         return None
>> >     if require_exactly_one and len(threads) != 1:
>> > @@ -575,6 +578,9 @@ def get_one_thread_stopped_at_breakpoint
>> >
>> >     return threads[0]
>> >
>> > +def get_one_thread_stopped_at_breakpoint(process, bkpt,
>> require_exactly_one = True):
>> > +    return get_one_thread_stopped_at_breakpoint_id(bkpt.GetID(),
>> require_exactly_one)
>> > +
>> > def is_thread_crashed (test, thread):
>> >     """In the test suite we dereference a null pointer to simulate a
>> crash. The way this is
>> >     reported depends on the platform."""
>> >
>> >
>> > _______________________________________________
>> > lldb-commits mailing list
>> > lldb-commits at lists.llvm.org
>> > http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20160123/a2bd1a98/attachment-0001.html>


More information about the lldb-commits mailing list