diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:26:05 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:26:05 +0000 | 
| commit | 14f1b3e8826ce43b978db93a62d1166055db5394 (patch) | |
| tree | 0a00ad8d3498783fe0193f3b656bca17c4c8697d /packages/Python/lldbsuite/test/functionalities/tsan | |
| parent | 4ee8c119c71a06dcad1e0fecc8c675e480e59337 (diff) | |
Notes
Diffstat (limited to 'packages/Python/lldbsuite/test/functionalities/tsan')
6 files changed, 199 insertions, 107 deletions
| diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py b/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py index 44fa9cedc86c..f1689a8fda00 100644 --- a/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py +++ b/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py @@ -2,25 +2,28 @@  Tests basic ThreadSanitizer support (detecting a data race).  """ -import os, time +import os +import time  import lldb  from lldbsuite.test.lldbtest import *  from lldbsuite.test.decorators import *  import lldbsuite.test.lldbutil as lldbutil  import json +  class TsanBasicTestCase(TestBase):      mydir = TestBase.compute_mydir(__file__) -    @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)") -    @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default +    @expectedFailureAll( +        oslist=["linux"], +        bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)") +    @skipIfFreeBSD  # llvm.org/pr21136 runtimes not yet available by default      @skipIfRemote -    @skipUnlessCompilerRt      @skipUnlessThreadSanitizer -    def test (self): -        self.build () -        self.tsan_tests () +    def test(self): +        self.build() +        self.tsan_tests()      def setUp(self):          # Call super's setUp(). @@ -29,26 +32,33 @@ class TsanBasicTestCase(TestBase):          self.line_thread1 = line_number('main.c', '// thread1 line')          self.line_thread2 = line_number('main.c', '// thread2 line') -    def tsan_tests (self): -        exe = os.path.join (os.getcwd(), "a.out") -        self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ]) +    def tsan_tests(self): +        exe = os.path.join(os.getcwd(), "a.out") +        self.expect( +            "file " + exe, +            patterns=["Current executable set to .*a.out"])          self.runCmd("run")          stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()          if stop_reason == lldb.eStopReasonExec: -            # On OS X 10.10 and older, we need to re-exec to enable interceptors. +            # On OS X 10.10 and older, we need to re-exec to enable +            # interceptors.              self.runCmd("continue")          # the stop reason of the thread should be breakpoint.          self.expect("thread list", "A data race should be detected", -            substrs = ['stopped', 'stop reason = Data race detected']) +                    substrs=['stopped', 'stop reason = Data race detected']) -        self.assertEqual(self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(), lldb.eStopReasonInstrumentation) +        self.assertEqual( +            self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(), +            lldb.eStopReasonInstrumentation)          # test that the TSan dylib is present -        self.expect("image lookup -n __tsan_get_current_report", "__tsan_get_current_report should be present", -            substrs = ['1 match found']) +        self.expect( +            "image lookup -n __tsan_get_current_report", +            "__tsan_get_current_report should be present", +            substrs=['1 match found'])          # We should be stopped in __tsan_on_report          process = self.dbg.GetSelectedTarget().process @@ -56,7 +66,8 @@ class TsanBasicTestCase(TestBase):          frame = thread.GetSelectedFrame()          self.assertTrue("__tsan_on_report" in frame.GetFunctionName()) -        # The stopped thread backtrace should contain either line1 or line2 from main.c. +        # The stopped thread backtrace should contain either line1 or line2 +        # from main.c.          found = False          for i in range(0, thread.GetNumFrames()):              frame = thread.GetFrameAtIndex(i) @@ -67,8 +78,13 @@ class TsanBasicTestCase(TestBase):                      found = True          self.assertTrue(found) -        self.expect("thread info -s", "The extended stop info should contain the TSan provided fields", -            substrs = ["instrumentation_class", "description", "mops"]) +        self.expect( +            "thread info -s", +            "The extended stop info should contain the TSan provided fields", +            substrs=[ +                "instrumentation_class", +                "description", +                "mops"])          output_lines = self.res.GetOutput().split('\n')          json_line = '\n'.join(output_lines[2:]) @@ -77,10 +93,12 @@ class TsanBasicTestCase(TestBase):          self.assertEqual(data["issue_type"], "data-race")          self.assertEqual(len(data["mops"]), 2) -        backtraces = thread.GetStopReasonExtendedBacktraces(lldb.eInstrumentationRuntimeTypeAddressSanitizer) +        backtraces = thread.GetStopReasonExtendedBacktraces( +            lldb.eInstrumentationRuntimeTypeAddressSanitizer)          self.assertEqual(backtraces.GetSize(), 0) -        backtraces = thread.GetStopReasonExtendedBacktraces(lldb.eInstrumentationRuntimeTypeThreadSanitizer) +        backtraces = thread.GetStopReasonExtendedBacktraces( +            lldb.eInstrumentationRuntimeTypeThreadSanitizer)          self.assertTrue(backtraces.GetSize() >= 2)          # First backtrace is a memory operation @@ -111,8 +129,8 @@ class TsanBasicTestCase(TestBase):          # the stop reason of the thread should be a SIGABRT.          self.expect("thread list", "We should be stopped due a SIGABRT", -            substrs = ['stopped', 'stop reason = signal SIGABRT']) +                    substrs=['stopped', 'stop reason = signal SIGABRT'])          # test that we're in pthread_kill now (TSan abort the process)          self.expect("thread list", "We should be stopped in pthread_kill", -            substrs = ['pthread_kill']) +                    substrs=['pthread_kill']) diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/TestTsanCPPGlobalLocation.py b/packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/TestTsanCPPGlobalLocation.py index 230ff982da0d..8baba9beed36 100644 --- a/packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/TestTsanCPPGlobalLocation.py +++ b/packages/Python/lldbsuite/test/functionalities/tsan/cpp_global_location/TestTsanCPPGlobalLocation.py @@ -2,47 +2,58 @@  Tests that TSan correctly reports the filename and line number of a racy global C++ variable.  """ -import os, time +import os +import time  import lldb  from lldbsuite.test.lldbtest import *  from lldbsuite.test.decorators import *  import lldbsuite.test.lldbutil as lldbutil  import json +  class TsanCPPGlobalLocationTestCase(TestBase):      mydir = TestBase.compute_mydir(__file__) -    @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)") -    @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default +    @expectedFailureAll( +        oslist=["linux"], +        bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)") +    @skipIfFreeBSD  # llvm.org/pr21136 runtimes not yet available by default      @skipIfRemote -    @skipUnlessCompilerRt      @skipUnlessThreadSanitizer -    def test (self): -        self.build () -        self.tsan_tests () +    def test(self): +        self.build() +        self.tsan_tests()      def setUp(self):          # Call super's setUp().          TestBase.setUp(self) -    def tsan_tests (self): -        exe = os.path.join (os.getcwd(), "a.out") -        self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ]) +    def tsan_tests(self): +        exe = os.path.join(os.getcwd(), "a.out") +        self.expect( +            "file " + exe, +            patterns=["Current executable set to .*a.out"])          self.runCmd("run")          stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()          if stop_reason == lldb.eStopReasonExec: -            # On OS X 10.10 and older, we need to re-exec to enable interceptors. +            # On OS X 10.10 and older, we need to re-exec to enable +            # interceptors.              self.runCmd("continue")          # the stop reason of the thread should be breakpoint.          self.expect("thread list", "A data race should be detected", -            substrs = ['stopped', 'stop reason = Data race detected']) +                    substrs=['stopped', 'stop reason = Data race detected']) -        self.expect("thread info -s", "The extended stop info should contain the TSan provided fields", -            substrs = ["instrumentation_class", "description", "mops"]) +        self.expect( +            "thread info -s", +            "The extended stop info should contain the TSan provided fields", +            substrs=[ +                "instrumentation_class", +                "description", +                "mops"])          output_lines = self.res.GetOutput().split('\n')          json_line = '\n'.join(output_lines[2:]) @@ -51,4 +62,8 @@ class TsanCPPGlobalLocationTestCase(TestBase):          self.assertEqual(data["issue_type"], "data-race")          self.assertTrue(data["location_filename"].endswith("/main.cpp")) -        self.assertEqual(data["location_line"], line_number('main.cpp', '// global variable')) +        self.assertEqual( +            data["location_line"], +            line_number( +                'main.cpp', +                '// global variable')) diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/global_location/TestTsanGlobalLocation.py b/packages/Python/lldbsuite/test/functionalities/tsan/global_location/TestTsanGlobalLocation.py index b268c46fead3..3f0cae6a54c9 100644 --- a/packages/Python/lldbsuite/test/functionalities/tsan/global_location/TestTsanGlobalLocation.py +++ b/packages/Python/lldbsuite/test/functionalities/tsan/global_location/TestTsanGlobalLocation.py @@ -2,53 +2,68 @@  Tests that TSan correctly reports the filename and line number of a racy global variable.  """ -import os, time +import os +import time  import lldb  from lldbsuite.test.lldbtest import *  from lldbsuite.test.decorators import *  import lldbsuite.test.lldbutil as lldbutil  import json +  class TsanGlobalLocationTestCase(TestBase):      mydir = TestBase.compute_mydir(__file__) -    @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)") -    @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default +    @expectedFailureAll( +        oslist=["linux"], +        bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)") +    @skipIfFreeBSD  # llvm.org/pr21136 runtimes not yet available by default      @skipIfRemote -    @skipUnlessCompilerRt      @skipUnlessThreadSanitizer -    def test (self): -        self.build () -        self.tsan_tests () +    def test(self): +        self.build() +        self.tsan_tests()      def setUp(self):          # Call super's setUp().          TestBase.setUp(self) -    def tsan_tests (self): -        exe = os.path.join (os.getcwd(), "a.out") -        self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ]) +    def tsan_tests(self): +        exe = os.path.join(os.getcwd(), "a.out") +        self.expect( +            "file " + exe, +            patterns=["Current executable set to .*a.out"])          self.runCmd("run")          stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()          if stop_reason == lldb.eStopReasonExec: -            # On OS X 10.10 and older, we need to re-exec to enable interceptors. +            # On OS X 10.10 and older, we need to re-exec to enable +            # interceptors.              self.runCmd("continue")          # the stop reason of the thread should be breakpoint.          self.expect("thread list", "A data race should be detected", -            substrs = ['stopped', 'stop reason = Data race detected']) +                    substrs=['stopped', 'stop reason = Data race detected']) -        self.expect("thread info -s", "The extended stop info should contain the TSan provided fields", -            substrs = ["instrumentation_class", "description", "mops"]) +        self.expect( +            "thread info -s", +            "The extended stop info should contain the TSan provided fields", +            substrs=[ +                "instrumentation_class", +                "description", +                "mops"])          output_lines = self.res.GetOutput().split('\n')          json_line = '\n'.join(output_lines[2:])          data = json.loads(json_line)          self.assertEqual(data["instrumentation_class"], "ThreadSanitizer")          self.assertEqual(data["issue_type"], "data-race") -         +          self.assertTrue(data["location_filename"].endswith("/main.c")) -        self.assertEqual(data["location_line"], line_number('main.c', '// global variable')) +        self.assertEqual( +            data["location_line"], +            line_number( +                'main.c', +                '// global variable')) diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/multiple/TestTsanMultiple.py b/packages/Python/lldbsuite/test/functionalities/tsan/multiple/TestTsanMultiple.py index c22501141cca..436fcf63d07d 100644 --- a/packages/Python/lldbsuite/test/functionalities/tsan/multiple/TestTsanMultiple.py +++ b/packages/Python/lldbsuite/test/functionalities/tsan/multiple/TestTsanMultiple.py @@ -2,33 +2,38 @@  Test ThreadSanitizer when multiple different issues are found.  """ -import os, time +import os +import time  import lldb  from lldbsuite.test.lldbtest import *  from lldbsuite.test.decorators import *  import lldbsuite.test.lldbutil as lldbutil  import json +  class TsanMultipleTestCase(TestBase):      mydir = TestBase.compute_mydir(__file__) -    @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)") -    @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default +    @expectedFailureAll( +        oslist=["linux"], +        bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)") +    @skipIfFreeBSD  # llvm.org/pr21136 runtimes not yet available by default      @skipIfRemote -    @skipUnlessCompilerRt      @skipUnlessThreadSanitizer -    def test (self): -        self.build () -        self.tsan_tests () +    def test(self): +        self.build() +        self.tsan_tests()      def setUp(self):          # Call super's setUp().          TestBase.setUp(self) -    def tsan_tests (self): -        exe = os.path.join (os.getcwd(), "a.out") -        self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ]) +    def tsan_tests(self): +        exe = os.path.join(os.getcwd(), "a.out") +        self.expect( +            "file " + exe, +            patterns=["Current executable set to .*a.out"])          self.runCmd("env TSAN_OPTIONS=abort_on_error=0") @@ -36,34 +41,46 @@ class TsanMultipleTestCase(TestBase):          stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()          if stop_reason == lldb.eStopReasonExec: -            # On OS X 10.10 and older, we need to re-exec to enable interceptors. +            # On OS X 10.10 and older, we need to re-exec to enable +            # interceptors.              self.runCmd("continue")          report_count = 0 -        while self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason() == lldb.eStopReasonInstrumentation: +        while self.dbg.GetSelectedTarget().process.GetSelectedThread( +        ).GetStopReason() == lldb.eStopReasonInstrumentation:              report_count += 1 -            stop_description = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopDescription(100) +            stop_description = self.dbg.GetSelectedTarget( +            ).process.GetSelectedThread().GetStopDescription(100)              self.assertTrue( -                 (stop_description == "Data race detected") or -                 (stop_description == "Use of deallocated memory detected") or -                 (stop_description == "Thread leak detected") or -                 (stop_description == "Use of an uninitialized or destroyed mutex detected") or -                 (stop_description == "Unlock of an unlocked mutex (or by a wrong thread) detected") +                (stop_description == "Data race detected") or +                (stop_description == "Use of deallocated memory detected") or +                (stop_description == "Thread leak detected") or +                (stop_description == "Use of an uninitialized or destroyed mutex detected") or +                (stop_description == "Unlock of an unlocked mutex (or by a wrong thread) detected")              ) -            self.expect("thread info -s", "The extended stop info should contain the TSan provided fields", -                substrs = ["instrumentation_class", "description", "mops"]) +            self.expect( +                "thread info -s", +                "The extended stop info should contain the TSan provided fields", +                substrs=[ +                    "instrumentation_class", +                    "description", +                    "mops"])              output_lines = self.res.GetOutput().split('\n')              json_line = '\n'.join(output_lines[2:])              data = json.loads(json_line)              self.assertEqual(data["instrumentation_class"], "ThreadSanitizer") -            backtraces = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReasonExtendedBacktraces(lldb.eInstrumentationRuntimeTypeThreadSanitizer) +            backtraces = self.dbg.GetSelectedTarget().process.GetSelectedThread( +            ).GetStopReasonExtendedBacktraces(lldb.eInstrumentationRuntimeTypeThreadSanitizer)              self.assertTrue(backtraces.GetSize() >= 1)              self.runCmd("continue") -        self.assertEqual(self.dbg.GetSelectedTarget().process.GetState(), lldb.eStateExited, PROCESS_EXITED) +        self.assertEqual( +            self.dbg.GetSelectedTarget().process.GetState(), +            lldb.eStateExited, +            PROCESS_EXITED) diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/TestTsanThreadLeak.py b/packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/TestTsanThreadLeak.py index ed620093c1f3..f4380cf7749a 100644 --- a/packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/TestTsanThreadLeak.py +++ b/packages/Python/lldbsuite/test/functionalities/tsan/thread_leak/TestTsanThreadLeak.py @@ -2,39 +2,47 @@  Tests ThreadSanitizer's support to detect a leaked thread.  """ -import os, time +import os +import time  import lldb  from lldbsuite.test.lldbtest import *  from lldbsuite.test.decorators import *  import lldbsuite.test.lldbutil as lldbutil  import json +  class TsanThreadLeakTestCase(TestBase):      mydir = TestBase.compute_mydir(__file__) -    @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)") -    @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default +    @expectedFailureAll( +        oslist=["linux"], +        bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)") +    @skipIfFreeBSD  # llvm.org/pr21136 runtimes not yet available by default      @skipIfRemote -    @skipUnlessCompilerRt      @skipUnlessThreadSanitizer -    def test (self): -        self.build () -        self.tsan_tests () +    def test(self): +        self.build() +        self.tsan_tests() -    def tsan_tests (self): -        exe = os.path.join (os.getcwd(), "a.out") -        self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ]) +    def tsan_tests(self): +        exe = os.path.join(os.getcwd(), "a.out") +        self.expect( +            "file " + exe, +            patterns=["Current executable set to .*a.out"])          self.runCmd("run")          stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()          if stop_reason == lldb.eStopReasonExec: -            # On OS X 10.10 and older, we need to re-exec to enable interceptors. +            # On OS X 10.10 and older, we need to re-exec to enable +            # interceptors.              self.runCmd("continue")          # the stop reason of the thread should be breakpoint.          self.expect("thread list", "A thread leak should be detected", -            substrs = ['stopped', 'stop reason = Thread leak detected']) +                    substrs=['stopped', 'stop reason = Thread leak detected']) -        self.assertEqual(self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(), lldb.eStopReasonInstrumentation) +        self.assertEqual( +            self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(), +            lldb.eStopReasonInstrumentation) diff --git a/packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/TestTsanThreadNumbers.py b/packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/TestTsanThreadNumbers.py index c7905bcb1c1d..684e6f71d931 100644 --- a/packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/TestTsanThreadNumbers.py +++ b/packages/Python/lldbsuite/test/functionalities/tsan/thread_numbers/TestTsanThreadNumbers.py @@ -2,51 +2,65 @@  Tests that TSan and LLDB have correct thread numbers.  """ -import os, time +import os +import time  import lldb  from lldbsuite.test.lldbtest import *  from lldbsuite.test.decorators import *  import lldbsuite.test.lldbutil as lldbutil  import json +  class TsanThreadNumbersTestCase(TestBase):      mydir = TestBase.compute_mydir(__file__) -    @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)") -    @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default +    @expectedFailureAll( +        oslist=["linux"], +        bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)") +    @skipIfFreeBSD  # llvm.org/pr21136 runtimes not yet available by default      @skipIfRemote -    @skipUnlessCompilerRt      @skipUnlessThreadSanitizer -    def test (self): -        self.build () -        self.tsan_tests () +    def test(self): +        self.build() +        self.tsan_tests()      def setUp(self):          # Call super's setUp().          TestBase.setUp(self) -    def tsan_tests (self): -        exe = os.path.join (os.getcwd(), "a.out") -        self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ]) +    def tsan_tests(self): +        exe = os.path.join(os.getcwd(), "a.out") +        self.expect( +            "file " + exe, +            patterns=["Current executable set to .*a.out"])          self.runCmd("run")          stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()          if stop_reason == lldb.eStopReasonExec: -            # On OS X 10.10 and older, we need to re-exec to enable interceptors. +            # On OS X 10.10 and older, we need to re-exec to enable +            # interceptors.              self.runCmd("continue")          # the stop reason of the thread should be breakpoint.          self.expect("thread list", "A data race should be detected", -            substrs = ['stopped', 'stop reason = Data race detected']) +                    substrs=['stopped', 'stop reason = Data race detected']) -        self.assertEqual(self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(), lldb.eStopReasonInstrumentation) +        self.assertEqual( +            self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(), +            lldb.eStopReasonInstrumentation) -        report_thread_id = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetIndexID() +        report_thread_id = self.dbg.GetSelectedTarget( +        ).process.GetSelectedThread().GetIndexID() -        self.expect("thread info -s", "The extended stop info should contain the TSan provided fields", -            substrs = ["instrumentation_class", "description", "mops"]) +        self.expect( +            "thread info -s", +            "The extended stop info should contain the TSan provided fields", +            substrs=[ +                "instrumentation_class", +                "description", +                "mops"])          output_lines = self.res.GetOutput().split('\n')          json_line = '\n'.join(output_lines[2:]) @@ -59,10 +73,15 @@ class TsanThreadNumbersTestCase(TestBase):          other_thread_id = data["mops"][1]["thread_id"]          self.assertTrue(other_thread_id != report_thread_id) -        other_thread = self.dbg.GetSelectedTarget().process.GetThreadByIndexID(other_thread_id) +        other_thread = self.dbg.GetSelectedTarget( +        ).process.GetThreadByIndexID(other_thread_id)          self.assertTrue(other_thread.IsValid())          self.runCmd("thread select %d" % other_thread_id) -        self.expect("thread backtrace", "The other thread should be stopped in f1 or f2", -            substrs = ["a.out", "main.c"]) +        self.expect( +            "thread backtrace", +            "The other thread should be stopped in f1 or f2", +            substrs=[ +                "a.out", +                "main.c"]) | 
