Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(137)

Unified Diff: base/native_library_mac.mm

Issue 12827003: Another way to handle not unloading objc modules. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/native_library.h ('k') | content/ppapi_plugin/ppapi_thread.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/native_library_mac.mm
diff --git a/base/native_library_mac.mm b/base/native_library_mac.mm
index eec586b863588d9856cc0221da1e73973e10e8de..58fc3be93ba220a6394ce3fc4519eae0333f4365 100644
--- a/base/native_library_mac.mm
+++ b/base/native_library_mac.mm
@@ -5,19 +5,113 @@
#include "base/native_library.h"
#include <dlfcn.h>
+#include <mach/task_info.h>
+#include <mach-o/dyld_images.h>
+#include <mach-o/getsect.h>
#include "base/file_util.h"
#include "base/files/file_path.h"
+#include "base/lazy_instance.h"
+#include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/string_util.h"
+#include "base/synchronization/lock.h"
#include "base/threading/thread_restrictions.h"
#include "base/utf_string_conversions.h"
+extern "C" {
+
+// http://opensource.apple.com/source/dyld/dyld-195.5/include/mach-o/dyld_priv.h
+enum dyld_image_states
+{
+ dyld_image_state_mapped = 10, // No batch notification for this
+ dyld_image_state_dependents_mapped = 20, // Only batch notification for this
+ dyld_image_state_rebased = 30,
+ dyld_image_state_bound = 40,
+ dyld_image_state_dependents_initialized = 45, // Only single notification for this
+ dyld_image_state_initialized = 50,
+ dyld_image_state_terminated = 60 // Only single notification for this
+};
+
+typedef const char* (*dyld_image_state_change_handler)(
+ enum dyld_image_states state, uint32_t infoCount,
+ const struct dyld_image_info info[]);
+
+void dyld_register_image_state_change_handler(
+ enum dyld_image_states state, bool batch,
+ dyld_image_state_change_handler handler);
+
+};
+
+namespace {
+
+base::LazyInstance<base::Lock>::Leaky g_module_lock_ =
+ LAZY_INSTANCE_INITIALIZER;
+base::LazyInstance<std::set<std::string> >::Leaky g_module_set_ =
+ LAZY_INSTANCE_INITIALIZER;
+
+bool g_initial_registration = false;
+
+const char* Recorder(enum dyld_image_states state,
+ uint32_t infoCount,
+ const struct dyld_image_info info[]) {
+ if (g_initial_registration)
+ return NULL;
+
+ for (uint32_t i = 0; i < infoCount; i++) {
+#if __LP64__
+ const struct mach_header_64* hdr =
+ reinterpret_cast<const struct mach_header_64*>(
+ info[i].imageLoadAddress);
+
+ if (hdr->magic != MH_MAGIC_64 && hdr->magic != MH_CIGAM_64)
+ continue;
+
+ if (getsectbynamefromheader_64(hdr, SEG_DATA, "__objc_imageinfo")) {
+ LOG(ERROR) << "64-bit Objective-C found";
+ LOG(ERROR) << "info[i].imageFilePath: " << info[i].imageFilePath;
+ base::AutoLock pin(*g_module_lock_.Pointer());
+ g_module_set_.Pointer()->insert(info[i].imageFilePath);
+ }
+#else
+ const struct mach_header* hdr =
+ reinterpret_cast<const struct mach_header*>(
+ info[i].imageLoadAddress);
+
+ if (hdr->magic != MH_MAGIC && hdr->magic != MH_CIGAM)
+ continue;
+
+ if (getsectbynamefromheader(hdr, SEG_OBJC, "__image_info")) {
+ LOG(ERROR) << "32-bit Objective-C found";
+ LOG(ERROR) << "info[i].imageFilePath: " << info[i].imageFilePath;
+ base::AutoLock pin(*g_module_lock_.Pointer());
+ g_module_set_.Pointer()->insert(info[i].imageFilePath);
+ }
+#endif
+ }
+ return NULL;
+}
+
+void Initialize() {
+ static bool initialized = false;
+ if (!initialized) {
+ initialized = true;
+ g_initial_registration = true;
+ dyld_register_image_state_change_handler(dyld_image_state_mapped, 0 /* \
+batch */, &Recorder);
+ g_initial_registration = false;
+ }
+}
+
+} // namespace
+
namespace base {
// static
NativeLibrary LoadNativeLibrary(const base::FilePath& library_path,
std::string* error) {
+ Initialize();
+
// dlopen() etc. open the file off disk.
if (library_path.Extension() == "dylib" ||
!file_util::DirectoryExists(library_path)) {
@@ -27,6 +121,7 @@ NativeLibrary LoadNativeLibrary(const base::FilePath& library_path,
NativeLibrary native_lib = new NativeLibraryStruct();
native_lib->type = DYNAMIC_LIB;
native_lib->dylib = dylib;
+ native_lib->image_path = library_path;
return native_lib;
}
base::mac::ScopedCFTypeRef<CFURLRef> url(
@@ -45,17 +140,31 @@ NativeLibrary LoadNativeLibrary(const base::FilePath& library_path,
native_lib->type = BUNDLE;
native_lib->bundle = bundle;
native_lib->bundle_resource_ref = CFBundleOpenBundleResourceMap(bundle);
+
+ base::mac::ScopedCFTypeRef<CFURLRef> executable_url(
+ CFBundleCopyExecutableURL(bundle));
+ NSURL* executable_url_ns = base::mac::CFToNSCast(executable_url);
+ native_lib->image_path =
+ base::FilePath([[executable_url_ns path] fileSystemRepresentation]);
+
return native_lib;
}
// static
void UnloadNativeLibrary(NativeLibrary library) {
- if (library->type == BUNDLE) {
- CFBundleCloseBundleResourceMap(library->bundle,
- library->bundle_resource_ref);
- CFRelease(library->bundle);
- } else {
- dlclose(library->dylib);
+ bool unload = true;
+ {
+ base::AutoLock pin(*g_module_lock_.Pointer());
+ unload = !g_module_set_.Pointer()->count(library->image_path.value().c_str());
+ }
+ if (unload) {
+ if (library->type == BUNDLE) {
+ CFBundleCloseBundleResourceMap(library->bundle,
+ library->bundle_resource_ref);
+ CFRelease(library->bundle);
+ } else {
+ dlclose(library->dylib);
+ }
}
delete library;
}
« no previous file with comments | « base/native_library.h ('k') | content/ppapi_plugin/ppapi_thread.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698