[Lldb-commits] [lldb] r237935 - dotest.py - debug feature that helps find dosep races

Vince Harron vince at nethacker.com
Thu May 21 12:09:29 PDT 2015


Author: vharron
Date: Thu May 21 14:09:29 2015
New Revision: 237935

URL: http://llvm.org/viewvc/llvm-project?rev=237935&view=rev
Log:
dotest.py - debug feature that helps find dosep races

SUMMARY
dosep.py starts lots and lots of dotest instances.

This option helps you find if two (or more) dotest instances are using
the same directory at the same time.

Enable it to cause test failures and stderr messages if dotest
instances try to run in the same directory simultaneously.

It is disabled by default because it litters the test directories with
".dirlock" files

TEST PLAN
Set lldbtest.debug_confirm_directory_exclusivity = True
run ./dosep.py

Differential Revision: http://reviews.llvm.org/D9868


Modified:
    lldb/trunk/test/lldbtest.py
    lldb/trunk/test/lock.py

Modified: lldb/trunk/test/lldbtest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=237935&r1=237934&r2=237935&view=diff
==============================================================================
--- lldb/trunk/test/lldbtest.py (original)
+++ lldb/trunk/test/lldbtest.py Thu May 21 14:09:29 2015
@@ -33,6 +33,7 @@ $
 
 import abc
 import glob
+import lock
 import os, sys, traceback
 import os.path
 import re
@@ -47,6 +48,14 @@ import lldbtest_config
 import lldbutil
 from _pyio import __metaclass__
 
+# dosep.py starts lots and lots of dotest instances
+# This option helps you find if two (or more) dotest instances are using the same
+# directory at the same time
+# Enable it to cause test failures and stderr messages if dotest instances try to run in
+# the same directory simultaneously
+# it is disabled by default because it litters the test directories with ".dirlock" files
+debug_confirm_directory_exclusivity = False
+
 # See also dotest.parseOptionsAndInitTestdirs(), where the environment variables
 # LLDB_COMMAND_TRACE and LLDB_DO_CLEANUP are set from '-t' and '-r dir' options.
 
@@ -936,7 +945,6 @@ class Base(unittest2.TestCase):
         Python unittest framework class setup fixture.
         Do current directory manipulation.
         """
-
         # Fail fast if 'mydir' attribute is not overridden.
         if not cls.mydir or len(cls.mydir) == 0:
             raise Exception("Subclasses must override the 'mydir' attribute.")
@@ -947,10 +955,26 @@ class Base(unittest2.TestCase):
         # Change current working directory if ${LLDB_TEST} is defined.
         # See also dotest.py which sets up ${LLDB_TEST}.
         if ("LLDB_TEST" in os.environ):
+            full_dir = os.path.join(os.environ["LLDB_TEST"], cls.mydir)
             if traceAlways:
-                print >> sys.stderr, "Change dir to:", os.path.join(os.environ["LLDB_TEST"], cls.mydir)
+                print >> sys.stderr, "Change dir to:", full_dir
             os.chdir(os.path.join(os.environ["LLDB_TEST"], cls.mydir))
 
+        if debug_confirm_directory_exclusivity:
+            cls.dir_lock = lock.Lock(os.path.join(full_dir, ".dirlock"))
+            try:
+                cls.dir_lock.try_acquire()
+                # write the class that owns the lock into the lock file
+                cls.dir_lock.handle.write(cls.__name__)
+            except IOError as ioerror:
+                # nothing else should have this directory lock
+                # wait here until we get a lock
+                cls.dir_lock.acquire()
+                # read the previous owner from the lock file
+                lock_id = cls.dir_lock.handle.read()
+                print >> sys.stderr, "LOCK ERROR: {} wants to lock '{}' but it is already locked by '{}'".format(cls.__name__, full_dir, lock_id)
+                raise ioerror
+
         # Set platform context.
         if platformIsDarwin():
             cls.platformContext = _PlatformContext('DYLD_LIBRARY_PATH', 'lib', 'dylib')
@@ -982,6 +1006,10 @@ class Base(unittest2.TestCase):
                     exc_type, exc_value, exc_tb = sys.exc_info()
                     traceback.print_exception(exc_type, exc_value, exc_tb)
 
+        if debug_confirm_directory_exclusivity:
+            cls.dir_lock.release()
+            del cls.dir_lock
+
         # Restore old working directory.
         if traceAlways:
             print >> sys.stderr, "Restore dir to:", cls.oldcwd

Modified: lldb/trunk/test/lock.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lock.py?rev=237935&r1=237934&r2=237935&view=diff
==============================================================================
--- lldb/trunk/test/lock.py (original)
+++ lldb/trunk/test/lock.py Thu May 21 14:09:29 2015
@@ -10,12 +10,16 @@ class Lock:
     def __init__(self, filename):
         self.filename = filename
         # This will create it if it does not exist already
-        self.handle = open(filename, 'w')
+        unbuffered = 0
+        self.handle = open(filename, 'a+', unbuffered)
 
-    # Bitwise OR fcntl.LOCK_NB if you need a non-blocking lock
     def acquire(self):
         fcntl.flock(self.handle, fcntl.LOCK_EX)
 
+    # will throw IOError if unavailable
+    def try_acquire(self):
+        fcntl.flock(self.handle, fcntl.LOCK_NB | fcntl.LOCK_EX)
+
     def release(self):
         fcntl.flock(self.handle, fcntl.LOCK_UN)
 





More information about the lldb-commits mailing list