]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
lockdep: fix use after free; avoid register in unlocked() path
authorSage Weil <sage@newdream.net>
Mon, 1 Feb 2010 22:24:08 +0000 (14:24 -0800)
committerSage Weil <sage@newdream.net>
Mon, 1 Feb 2010 22:29:37 +0000 (14:29 -0800)
src/common/Mutex.h
src/common/RWLock.h
src/common/Spinlock.h
src/common/lockdep.cc
src/common/lockdep.h

index f0e8759cb3849ecf20b0d3b8ff5da6288550f5e7..7a6d67a8b60a964124e9ebddaaf61b60f1cc9c01 100755 (executable)
@@ -47,14 +47,14 @@ private:
   void _locked() {    // just locked
     id = lockdep_locked(name, id, backtrace);
   }
-  void _unlocked() {  // just unlocked
-    id = lockdep_unlocked(name, id);
+  void _will_unlock() {  // about to unlock
+    id = lockdep_will_unlock(name, id);
   }
 #else
   void _register() {}
   void _will_lock() {} // about to lock
   void _locked() {}    // just locked
-  void _unlocked() {}  // just unlocked
+  void _will_unlock() {}  // about to unlock
 #endif
 
 public:
@@ -100,9 +100,9 @@ public:
   void Unlock() {
     assert(nlock > 0);
     --nlock;
+    if (lockdep && g_lockdep) _will_unlock();
     int r = pthread_mutex_unlock(&_m);
     assert(r == 0);
-    if (lockdep && g_lockdep) _unlocked();
   }
 
   friend class Cond;
index e1065e2bba97c1301f1eca9650c0a2cb8c198bf5..7db72f07e3b8d8054a02a757148b1f4aa25504d5 100644 (file)
@@ -39,7 +39,7 @@ class RWLock
   }
 
   void unlock() {
-    if (g_lockdep) id = lockdep_unlocked(name, id);
+    if (g_lockdep) id = lockdep_will_unlock(name, id);
     pthread_rwlock_unlock(&L);
   }
 
index c0bba996a336afe7db45eddeca484339f8bcc06f..95598a3909120913b608acf6c4873ee04f063aa0 100644 (file)
@@ -45,14 +45,14 @@ private:
   void _locked() {    // just locked
     id = lockdep_locked(name, id, backtrace);
   }
-  void _unlocked() {  // just unlocked
-    id = lockdep_unlocked(name, id);
+  void _will_unlock() {  // about to unlock
+    id = lockdep_will_unlock(name, id);
   }
 #else
   void _register() {}
   void _will_lock() {} // about to lock
   void _locked() {}    // just locked
-  void _unlocked() {}  // just unlocked
+  void _will_unlock() {}  // about to unlock
 #endif
 
 public:
@@ -90,9 +90,9 @@ public:
   void unlock() {
     assert(nlock > 0);
     --nlock;
+    if (lockdep && g_lockdep) _will_unlock();
     int r = pthread_spin_unlock(&_s);
     assert(r == 0);
-    if (lockdep && g_lockdep) _unlocked();
   }
 
 public:
index 8b37dc18dd8efd16adfed940295d1dc1d1150965..ed5162bdbfc9926fa08ce8e79600be20751a6cf7 100644 (file)
@@ -210,14 +210,18 @@ int lockdep_locked(const char *name, int id, bool force_backtrace)
   return id;
 }
 
-int lockdep_unlocked(const char *name, int id)
+int lockdep_will_unlock(const char *name, int id)
 {
   pthread_t p = pthread_self();
   
-  if (id < 0) id = lockdep_register(name);
+  if (id < 0) {
+    //id = lockdep_register(name);
+    assert(id == -1);
+    return id;
+  }
 
   pthread_mutex_lock(&lockdep_mutex);
-  dout(20) << "_unlocked " << name << std::endl;
+  dout(20) << "_will_unlock " << name << std::endl;
 
   // don't assert.. lockdep may be enabled at any point in time
   //assert(held.count(p));
index f1303773a4fc94356511935d9b48e6ceb2ea9029..78784bcbbe04d37b481a9e8b33df75db3127b31d 100644 (file)
@@ -6,7 +6,7 @@ extern int g_lockdep;
 extern int lockdep_register(const char *n);
 extern int lockdep_will_lock(const char *n, int id);
 extern int lockdep_locked(const char *n, int id, bool force_backtrace=false);
-extern int lockdep_unlocked(const char *n, int id);
+extern int lockdep_will_unlock(const char *n, int id);
 extern int lockdep_dump_locks();
 
 #endif