[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