[Lldb-commits] [lldb] r325964 - [Utility] Simplify and generalize the CleanUp helper, NFC

Vedant Kumar via lldb-commits lldb-commits at lists.llvm.org
Fri Feb 23 14:08:39 PST 2018


Author: vedantk
Date: Fri Feb 23 14:08:38 2018
New Revision: 325964

URL: http://llvm.org/viewvc/llvm-project?rev=325964&view=rev
Log:
[Utility] Simplify and generalize the CleanUp helper, NFC

Removing the template arguments and most of the mutating methods from
CleanUp makes it easier to understand and reuse.

In its present state, CleanUp would be too cumbersome to adapt to cases
where multiple objects need to be released. Take for example this change
in swift-lldb:

  https://github.com/apple/swift-lldb/pull/334/files#diff-6f474df750f75c8ba675f2a8408a5629R219

This change is simple to express with the new CleanUp, but not so simple
with the old version.

Differential Revision: https://reviews.llvm.org/D43662

Added:
    lldb/trunk/unittests/Utility/CleanUpTest.cpp
Modified:
    lldb/trunk/include/lldb/Utility/CleanUp.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Host/macosx/Host.mm
    lldb/trunk/source/Host/macosx/Symbols.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/unittests/Utility/CMakeLists.txt

Modified: lldb/trunk/include/lldb/Utility/CleanUp.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/CleanUp.h?rev=325964&r1=325963&r2=325964&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Utility/CleanUp.h (original)
+++ lldb/trunk/include/lldb/Utility/CleanUp.h Fri Feb 23 14:08:38 2018
@@ -13,249 +13,31 @@
 #include "lldb/lldb-public.h"
 #include <functional>
 
-namespace lldb_utility {
+namespace lldb_private {
 
-//----------------------------------------------------------------------
-// Templated class that guarantees that a cleanup callback function will
-// be called. The cleanup function will be called once under the
-// following conditions:
-// - when the object goes out of scope
-// - when the user explicitly calls clean.
-// - the current value will be cleaned up when a new value is set using
-//   set(T value) as long as the current value hasn't already been cleaned.
-//
-// This class is designed to be used with simple types for type T (like
-// file descriptors, opaque handles, pointers, etc). If more complex
-// type T objects are desired, we need to probably specialize this class
-// to take "const T&" for all input T parameters. Yet if a type T is
-// complex already it might be better to build the cleanup functionality
-// into T.
-//
-// The cleanup function must take one argument that is of type T.
-// The calback function return type is R. The return value is currently
-// needed for "CallbackType". If there is an easy way to get around the
-// need for the return value we can change this class.
-//
-// The two template parameters are:
-//    T - The variable type of value that will be stored and used as the
-//      sole argument for the cleanup callback.
-//    R - The return type for the cleanup function.
-//
-// EXAMPLES
-//  // Use with file handles that get opened where you want to close
-//  // them. Below we use "int open(const char *path, int oflag, ...)"
-//  // which returns an integer file descriptor. -1 is the invalid file
-//  // descriptor so to make an object that will call "int close(int fd)"
-//  // automatically we can use:
-//
-//  CleanUp <int, int> fd(open("/tmp/a.txt", O_RDONLY, 0), -1, close);
-//
-//  // malloc/free example
-//  CleanUp <void *, void> malloced_bytes(malloc(32), NULL, free);
-//----------------------------------------------------------------------
-template <typename T, typename R = void> class CleanUp {
-public:
-  typedef T value_type;
-  typedef std::function<R(value_type)> CallbackType;
-
-  //----------------------------------------------------------------------
-  // Constructor that sets the current value only. No values are
-  // considered to be invalid and the cleanup function will be called
-  // regardless of the value of m_current_value.
-  //----------------------------------------------------------------------
-  CleanUp(value_type value, CallbackType callback)
-      : m_current_value(value), m_invalid_value(), m_callback(callback),
-        m_callback_called(false), m_invalid_value_is_valid(false) {}
-
-  //----------------------------------------------------------------------
-  // Constructor that sets the current value and also the invalid value.
-  // The cleanup function will be called on "m_value" as long as it isn't
-  // equal to "m_invalid_value".
-  //----------------------------------------------------------------------
-  CleanUp(value_type value, value_type invalid, CallbackType callback)
-      : m_current_value(value), m_invalid_value(invalid), m_callback(callback),
-        m_callback_called(false), m_invalid_value_is_valid(true) {}
-
-  //----------------------------------------------------------------------
-  // Automatically cleanup when this object goes out of scope.
-  //----------------------------------------------------------------------
-  ~CleanUp() { clean(); }
-
-  //----------------------------------------------------------------------
-  // Access the value stored in this class
-  //----------------------------------------------------------------------
-  value_type get() { return m_current_value; }
-
-  //----------------------------------------------------------------------
-  // Access the value stored in this class
-  //----------------------------------------------------------------------
-  const value_type get() const { return m_current_value; }
-
-  //----------------------------------------------------------------------
-  // Reset the owned value to "value". If a current value is valid and
-  // the cleanup callback hasn't been called, the previous value will
-  // be cleaned up (see void CleanUp::clean()).
-  //----------------------------------------------------------------------
-  void set(const value_type value) {
-    // Cleanup the current value if needed
-    clean();
-    // Now set the new value and mark our callback as not called
-    m_callback_called = false;
-    m_current_value = value;
-  }
-
-  //----------------------------------------------------------------------
-  // Checks is "m_current_value" is valid. The value is considered valid
-  // no invalid value was supplied during construction of this object or
-  // if an invalid value was supplied and "m_current_value" is not equal
-  // to "m_invalid_value".
-  //
-  // Returns true if "m_current_value" is valid, false otherwise.
-  //----------------------------------------------------------------------
-  bool is_valid() const {
-    if (m_invalid_value_is_valid)
-      return m_current_value != m_invalid_value;
-    return true;
-  }
-
-  //----------------------------------------------------------------------
-  // This function will call the cleanup callback provided in the
-  // constructor one time if the value is considered valid (See is_valid()).
-  // This function sets m_callback_called to true so we don't call the
-  // cleanup callback multiple times on the same value.
-  //----------------------------------------------------------------------
-  void clean() {
-    if (m_callback && !m_callback_called) {
-      m_callback_called = true;
-      if (is_valid())
-        m_callback(m_current_value);
-    }
-  }
-
-  //----------------------------------------------------------------------
-  // Cancels the cleanup that would have been called on "m_current_value"
-  // if it was valid. This function can be used to release the value
-  // contained in this object so ownership can be transferred to the caller.
-  //----------------------------------------------------------------------
-  value_type release() {
-    m_callback_called = true;
-    return m_current_value;
-  }
-
-private:
-  value_type m_current_value;
-  const value_type m_invalid_value;
-  CallbackType m_callback;
-  bool m_callback_called;
-  bool m_invalid_value_is_valid;
+/// Run a cleanup function on scope exit unless it's explicitly disabled.
+class CleanUp {
+  std::function<void()> Clean;
 
-  // Outlaw default constructor, copy constructor and the assignment operator
-  DISALLOW_COPY_AND_ASSIGN(CleanUp);
-};
-
-template <typename T, typename R, typename A0> class CleanUp2 {
 public:
-  typedef T value_type;
-  typedef std::function<R(value_type, A0)> CallbackType;
-
-  //----------------------------------------------------------------------
-  // Constructor that sets the current value only. No values are
-  // considered to be invalid and the cleanup function will be called
-  // regardless of the value of m_current_value.
-  //----------------------------------------------------------------------
-  CleanUp2(value_type value, CallbackType callback, A0 arg)
-      : m_current_value(value), m_invalid_value(), m_callback(callback),
-        m_callback_called(false), m_invalid_value_is_valid(false),
-        m_argument(arg) {}
-
-  //----------------------------------------------------------------------
-  // Constructor that sets the current value and also the invalid value.
-  // The cleanup function will be called on "m_value" as long as it isn't
-  // equal to "m_invalid_value".
-  //----------------------------------------------------------------------
-  CleanUp2(value_type value, value_type invalid, CallbackType callback, A0 arg)
-      : m_current_value(value), m_invalid_value(invalid), m_callback(callback),
-        m_callback_called(false), m_invalid_value_is_valid(true),
-        m_argument(arg) {}
-
-  //----------------------------------------------------------------------
-  // Automatically cleanup when this object goes out of scope.
-  //----------------------------------------------------------------------
-  ~CleanUp2() { clean(); }
-
-  //----------------------------------------------------------------------
-  // Access the value stored in this class
-  //----------------------------------------------------------------------
-  value_type get() { return m_current_value; }
-
-  //----------------------------------------------------------------------
-  // Access the value stored in this class
-  //----------------------------------------------------------------------
-  const value_type get() const { return m_current_value; }
-
-  //----------------------------------------------------------------------
-  // Reset the owned value to "value". If a current value is valid and
-  // the cleanup callback hasn't been called, the previous value will
-  // be cleaned up (see void CleanUp::clean()).
-  //----------------------------------------------------------------------
-  void set(const value_type value) {
-    // Cleanup the current value if needed
-    clean();
-    // Now set the new value and mark our callback as not called
-    m_callback_called = false;
-    m_current_value = value;
-  }
+  /// Register a cleanup function which applies \p Func to a list of arguments.
+  /// Use caution with arguments which are references: they will be copied.
+  template <typename F, typename... Args>
+  CleanUp(F &&Func, Args &&... args)
+      : Clean(std::bind(std::forward<F>(Func), std::forward<Args>(args)...)) {}
 
-  //----------------------------------------------------------------------
-  // Checks is "m_current_value" is valid. The value is considered valid
-  // no invalid value was supplied during construction of this object or
-  // if an invalid value was supplied and "m_current_value" is not equal
-  // to "m_invalid_value".
-  //
-  // Returns true if "m_current_value" is valid, false otherwise.
-  //----------------------------------------------------------------------
-  bool is_valid() const {
-    if (m_invalid_value_is_valid)
-      return m_current_value != m_invalid_value;
-    return true;
+  ~CleanUp() {
+    if (Clean)
+      Clean();
   }
 
-  //----------------------------------------------------------------------
-  // This function will call the cleanup callback provided in the
-  // constructor one time if the value is considered valid (See is_valid()).
-  // This function sets m_callback_called to true so we don't call the
-  // cleanup callback multiple times on the same value.
-  //----------------------------------------------------------------------
-  void clean() {
-    if (m_callback && !m_callback_called) {
-      m_callback_called = true;
-      if (is_valid())
-        m_callback(m_current_value, m_argument);
-    }
-  }
-
-  //----------------------------------------------------------------------
-  // Cancels the cleanup that would have been called on "m_current_value"
-  // if it was valid. This function can be used to release the value
-  // contained in this object so ownership can be transferred to the caller.
-  //----------------------------------------------------------------------
-  value_type release() {
-    m_callback_called = true;
-    return m_current_value;
-  }
+  /// Disable the cleanup.
+  void disable() { Clean = nullptr; }
 
-private:
-  value_type m_current_value;
-  const value_type m_invalid_value;
-  CallbackType m_callback;
-  bool m_callback_called;
-  bool m_invalid_value_is_valid;
-  A0 m_argument;
-
-  // Outlaw default constructor, copy constructor and the assignment operator
-  DISALLOW_COPY_AND_ASSIGN(CleanUp2);
+  // Prevent cleanups from being run more than once.
+  DISALLOW_COPY_AND_ASSIGN(CleanUp);
 };
 
-} // namespace lldb_utility
+} // namespace lldb_private
 
 #endif // #ifndef liblldb_CleanUp_h_

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=325964&r1=325963&r2=325964&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Feb 23 14:08:38 2018
@@ -770,6 +770,7 @@
 		6D99A3631BBC2F3200979793 /* ArmUnwindInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D99A3621BBC2F3200979793 /* ArmUnwindInfo.cpp */; };
 		6D9AB3DD1BB2B74E003F2289 /* TypeMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D9AB3DC1BB2B74E003F2289 /* TypeMap.cpp */; };
 		6DEC6F391BD66D750091ABA6 /* TaskPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6DEC6F381BD66D750091ABA6 /* TaskPool.cpp */; };
+		7F94D7182040A13A006EE3EA /* CleanUpTest.cpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7F94D7172040A13A006EE3EA /* CleanUpTest.cpp */; };
 		8C26C4261C3EA5F90031DF7C /* TSanRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C26C4241C3EA4340031DF7C /* TSanRuntime.cpp */; };
 		8C2D6A53197A1EAF006989C9 /* MemoryHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2D6A52197A1EAF006989C9 /* MemoryHistory.cpp */; };
 		8C2D6A5E197A250F006989C9 /* MemoryHistoryASan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2D6A5A197A1FDC006989C9 /* MemoryHistoryASan.cpp */; };
@@ -1242,6 +1243,7 @@
 			dstPath = "$(DEVELOPER_INSTALL_DIR)/usr/share/man/man1";
 			dstSubfolderSpec = 0;
 			files = (
+				7F94D7182040A13A006EE3EA /* CleanUpTest.cpp in CopyFiles */,
 				AF90106515AB7D3600FF120D /* lldb.1 in CopyFiles */,
 			);
 			runOnlyForDeploymentPostprocessing = 1;
@@ -2672,6 +2674,7 @@
 		6D9AB3DE1BB2B76B003F2289 /* TypeMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeMap.h; path = include/lldb/Symbol/TypeMap.h; sourceTree = "<group>"; };
 		6DEC6F381BD66D750091ABA6 /* TaskPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TaskPool.cpp; path = source/Host/common/TaskPool.cpp; sourceTree = "<group>"; };
 		6DEC6F3A1BD66D950091ABA6 /* TaskPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TaskPool.h; path = include/lldb/Host/TaskPool.h; sourceTree = "<group>"; };
+		7F94D7172040A13A006EE3EA /* CleanUpTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CleanUpTest.cpp; sourceTree = "<group>"; };
 		8C26C4241C3EA4340031DF7C /* TSanRuntime.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = TSanRuntime.cpp; path = TSan/TSanRuntime.cpp; sourceTree = "<group>"; };
 		8C26C4251C3EA4340031DF7C /* TSanRuntime.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TSanRuntime.h; path = TSan/TSanRuntime.h; sourceTree = "<group>"; };
 		8C2D6A52197A1EAF006989C9 /* MemoryHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MemoryHistory.cpp; path = source/Target/MemoryHistory.cpp; sourceTree = "<group>"; };
@@ -3419,6 +3422,7 @@
 		2321F9421BDD343A00BA9A93 /* Utility */ = {
 			isa = PBXGroup;
 			children = (
+				7F94D7172040A13A006EE3EA /* CleanUpTest.cpp */,
 				23E2E5161D903689006F38BB /* ArchSpecTest.cpp */,
 				9A3D43C81F3150D200EB767C /* ConstStringTest.cpp */,
 				9A3D43C71F3150D200EB767C /* LogTest.cpp */,

Modified: lldb/trunk/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=325964&r1=325963&r2=325964&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/Host.mm (original)
+++ lldb/trunk/source/Host/macosx/Host.mm Fri Feb 23 14:08:38 2018
@@ -1277,10 +1277,8 @@ static Status LaunchProcessPosixSpawn(co
     return error;
   }
 
-  // Make a quick class that will cleanup the posix spawn attributes in case
-  // we return in the middle of this function.
-  lldb_utility::CleanUp<posix_spawnattr_t *, int> posix_spawnattr_cleanup(
-      &attr, posix_spawnattr_destroy);
+  // Make sure we clean up the posix spawn attributes before exiting this scope.
+  CleanUp cleanup_attr(posix_spawnattr_destroy, &attr);
 
   sigset_t no_signals;
   sigset_t all_signals;
@@ -1382,11 +1380,8 @@ static Status LaunchProcessPosixSpawn(co
       return error;
     }
 
-    // Make a quick class that will cleanup the posix spawn attributes in case
-    // we return in the middle of this function.
-    lldb_utility::CleanUp<posix_spawn_file_actions_t *, int>
-        posix_spawn_file_actions_cleanup(&file_actions,
-                                         posix_spawn_file_actions_destroy);
+    // Make sure we clean up the posix file actions before exiting this scope.
+    CleanUp cleanup_fileact(posix_spawn_file_actions_destroy, &file_actions);
 
     for (size_t i = 0; i < num_file_actions; ++i) {
       const FileAction *launch_file_action =

Modified: lldb/trunk/source/Host/macosx/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Symbols.cpp?rev=325964&r1=325963&r2=325964&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/Symbols.cpp (original)
+++ lldb/trunk/source/Host/macosx/Symbols.cpp Fri Feb 23 14:08:38 2018
@@ -240,52 +240,53 @@ FileSpec Symbols::FindSymbolFileInBundle
                                          const lldb_private::UUID *uuid,
                                          const ArchSpec *arch) {
   char path[PATH_MAX];
+  if (dsym_bundle_fspec.GetPath(path, sizeof(path)) == 0)
+    return {};
 
-  FileSpec dsym_fspec;
+  ::strncat(path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1);
 
-  if (dsym_bundle_fspec.GetPath(path, sizeof(path))) {
-    ::strncat(path, "/Contents/Resources/DWARF",
-              sizeof(path) - strlen(path) - 1);
-
-    lldb_utility::CleanUp<DIR *, int> dirp(opendir(path), NULL, closedir);
-    if (dirp.is_valid()) {
-      dsym_fspec.GetDirectory().SetCString(path);
-      struct dirent *dp;
-      while ((dp = readdir(dirp.get())) != NULL) {
-        // Only search directories
-        if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) {
-          if (dp->d_namlen == 1 && dp->d_name[0] == '.')
-            continue;
+  DIR *dirp = opendir(path);
+  if (!dirp)
+    return {};
 
-          if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
-            continue;
-        }
+  // Make sure we close the directory before exiting this scope.
+  CleanUp cleanup_dir(closedir, dirp);
+
+  FileSpec dsym_fspec;
+  dsym_fspec.GetDirectory().SetCString(path);
+  struct dirent *dp;
+  while ((dp = readdir(dirp)) != NULL) {
+    // Only search directories
+    if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) {
+      if (dp->d_namlen == 1 && dp->d_name[0] == '.')
+        continue;
 
-        if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) {
-          dsym_fspec.GetFilename().SetCString(dp->d_name);
-          ModuleSpecList module_specs;
-          if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0,
-                                                  module_specs)) {
-            ModuleSpec spec;
-            for (size_t i = 0; i < module_specs.GetSize(); ++i) {
-              bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
-              UNUSED_IF_ASSERT_DISABLED(got_spec);
-              assert(got_spec);
-              if ((uuid == NULL ||
-                   (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
-                  (arch == NULL ||
-                   (spec.GetArchitecturePtr() &&
-                    spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
-                return dsym_fspec;
-              }
-            }
+      if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
+        continue;
+    }
+
+    if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) {
+      dsym_fspec.GetFilename().SetCString(dp->d_name);
+      ModuleSpecList module_specs;
+      if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs)) {
+        ModuleSpec spec;
+        for (size_t i = 0; i < module_specs.GetSize(); ++i) {
+          bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
+          UNUSED_IF_ASSERT_DISABLED(got_spec);
+          assert(got_spec);
+          if ((uuid == NULL ||
+               (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
+              (arch == NULL ||
+               (spec.GetArchitecturePtr() &&
+                spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
+            return dsym_fspec;
           }
         }
       }
     }
   }
-  dsym_fspec.Clear();
-  return dsym_fspec;
+
+  return {};
 }
 
 static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=325964&r1=325963&r2=325964&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri Feb 23 14:08:38 2018
@@ -3316,27 +3316,22 @@ Status ProcessGDBRemote::LaunchAndConnec
 
     int communication_fd = -1;
 #ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
-    // Auto close the sockets we might open up unless everything goes OK. This
-    // helps us not leak file descriptors when things go wrong.
-    lldb_utility::CleanUp<int, int> our_socket(-1, -1, close);
-    lldb_utility::CleanUp<int, int> gdb_socket(-1, -1, close);
-
     // Use a socketpair on non-Windows systems for security and performance
     // reasons.
-    {
-      int sockets[2]; /* the pair of socket descriptors */
-      if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) {
-        error.SetErrorToErrno();
-        return error;
-      }
-
-      our_socket.set(sockets[0]);
-      gdb_socket.set(sockets[1]);
+    int sockets[2]; /* the pair of socket descriptors */
+    if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) {
+      error.SetErrorToErrno();
+      return error;
     }
 
+    int our_socket = sockets[0];
+    int gdb_socket = sockets[1];
+    CleanUp cleanup_our(close, our_socket);
+    CleanUp cleanup_gdb(close, gdb_socket);
+
     // Don't let any child processes inherit our communication socket
-    SetCloexecFlag(our_socket.get());
-    communication_fd = gdb_socket.get();
+    SetCloexecFlag(our_socket);
+    communication_fd = gdb_socket;
 #endif
 
     error = m_gdb_comm.StartDebugserverProcess(
@@ -3352,8 +3347,8 @@ Status ProcessGDBRemote::LaunchAndConnec
 #ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
       // Our process spawned correctly, we can now set our connection to use our
       // end of the socket pair
-      m_gdb_comm.SetConnection(
-          new ConnectionFileDescriptor(our_socket.release(), true));
+      cleanup_our.disable();
+      m_gdb_comm.SetConnection(new ConnectionFileDescriptor(our_socket, true));
 #endif
       StartAsyncThread();
     }

Modified: lldb/trunk/unittests/Utility/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Utility/CMakeLists.txt?rev=325964&r1=325963&r2=325964&view=diff
==============================================================================
--- lldb/trunk/unittests/Utility/CMakeLists.txt (original)
+++ lldb/trunk/unittests/Utility/CMakeLists.txt Fri Feb 23 14:08:38 2018
@@ -1,5 +1,6 @@
 add_lldb_unittest(UtilityTests
   ArchSpecTest.cpp
+  CleanUpTest.cpp
   ConstStringTest.cpp
   EnvironmentTest.cpp
   JSONTest.cpp

Added: lldb/trunk/unittests/Utility/CleanUpTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Utility/CleanUpTest.cpp?rev=325964&view=auto
==============================================================================
--- lldb/trunk/unittests/Utility/CleanUpTest.cpp (added)
+++ lldb/trunk/unittests/Utility/CleanUpTest.cpp Fri Feb 23 14:08:38 2018
@@ -0,0 +1,47 @@
+//===-- CleanUpTest.cpp -----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/CleanUp.h"
+#include "gtest/gtest.h"
+
+using namespace lldb_private;
+
+TEST(CleanUpTest, no_args) {
+  bool f = false;
+  {
+    CleanUp cleanup([&] { f = true; });
+  }
+  ASSERT_TRUE(f);
+}
+
+TEST(CleanUpTest, multiple_args) {
+  bool f1 = false;
+  bool f2 = false;
+  bool f3 = false;
+  {
+    CleanUp cleanup(
+        [](bool arg1, bool *arg2, bool &arg3) {
+          ASSERT_FALSE(arg1);
+          *arg2 = true;
+          arg3 = true;
+        },
+        f1, &f2, f3);
+  }
+  ASSERT_TRUE(f2);
+  ASSERT_FALSE(f3);
+}
+
+TEST(CleanUpTest, disable) {
+  bool f = false;
+  {
+    CleanUp cleanup([&] { f = true; });
+    cleanup.disable();
+  }
+  ASSERT_FALSE(f);
+}




More information about the lldb-commits mailing list