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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/native_library.h ('k') | content/ppapi_plugin/ppapi_thread.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/native_library.h" 5 #include "base/native_library.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #include <mach/task_info.h>
9 #include <mach-o/dyld_images.h>
10 #include <mach-o/getsect.h>
8 11
9 #include "base/file_util.h" 12 #include "base/file_util.h"
10 #include "base/files/file_path.h" 13 #include "base/files/file_path.h"
14 #include "base/lazy_instance.h"
15 #include "base/mac/mac_util.h"
11 #include "base/mac/scoped_cftyperef.h" 16 #include "base/mac/scoped_cftyperef.h"
12 #include "base/string_util.h" 17 #include "base/string_util.h"
18 #include "base/synchronization/lock.h"
13 #include "base/threading/thread_restrictions.h" 19 #include "base/threading/thread_restrictions.h"
14 #include "base/utf_string_conversions.h" 20 #include "base/utf_string_conversions.h"
15 21
22 extern "C" {
23
24 // http://opensource.apple.com/source/dyld/dyld-195.5/include/mach-o/dyld_priv.h
25 enum dyld_image_states
26 {
27 dyld_image_state_mapped = 10, // No batch notification for this
28 dyld_image_state_dependents_mapped = 20, // Only batch notification for this
29 dyld_image_state_rebased = 30,
30 dyld_image_state_bound = 40,
31 dyld_image_state_dependents_initialized = 45, // Only single notification for this
32 dyld_image_state_initialized = 50,
33 dyld_image_state_terminated = 60 // Only single notification for thi s
34 };
35
36 typedef const char* (*dyld_image_state_change_handler)(
37 enum dyld_image_states state, uint32_t infoCount,
38 const struct dyld_image_info info[]);
39
40 void dyld_register_image_state_change_handler(
41 enum dyld_image_states state, bool batch,
42 dyld_image_state_change_handler handler);
43
44 };
45
46 namespace {
47
48 base::LazyInstance<base::Lock>::Leaky g_module_lock_ =
49 LAZY_INSTANCE_INITIALIZER;
50 base::LazyInstance<std::set<std::string> >::Leaky g_module_set_ =
51 LAZY_INSTANCE_INITIALIZER;
52
53 bool g_initial_registration = false;
54
55 const char* Recorder(enum dyld_image_states state,
56 uint32_t infoCount,
57 const struct dyld_image_info info[]) {
58 if (g_initial_registration)
59 return NULL;
60
61 for (uint32_t i = 0; i < infoCount; i++) {
62 #if __LP64__
63 const struct mach_header_64* hdr =
64 reinterpret_cast<const struct mach_header_64*>(
65 info[i].imageLoadAddress);
66
67 if (hdr->magic != MH_MAGIC_64 && hdr->magic != MH_CIGAM_64)
68 continue;
69
70 if (getsectbynamefromheader_64(hdr, SEG_DATA, "__objc_imageinfo")) {
71 LOG(ERROR) << "64-bit Objective-C found";
72 LOG(ERROR) << "info[i].imageFilePath: " << info[i].imageFilePath;
73 base::AutoLock pin(*g_module_lock_.Pointer());
74 g_module_set_.Pointer()->insert(info[i].imageFilePath);
75 }
76 #else
77 const struct mach_header* hdr =
78 reinterpret_cast<const struct mach_header*>(
79 info[i].imageLoadAddress);
80
81 if (hdr->magic != MH_MAGIC && hdr->magic != MH_CIGAM)
82 continue;
83
84 if (getsectbynamefromheader(hdr, SEG_OBJC, "__image_info")) {
85 LOG(ERROR) << "32-bit Objective-C found";
86 LOG(ERROR) << "info[i].imageFilePath: " << info[i].imageFilePath;
87 base::AutoLock pin(*g_module_lock_.Pointer());
88 g_module_set_.Pointer()->insert(info[i].imageFilePath);
89 }
90 #endif
91 }
92 return NULL;
93 }
94
95 void Initialize() {
96 static bool initialized = false;
97 if (!initialized) {
98 initialized = true;
99 g_initial_registration = true;
100 dyld_register_image_state_change_handler(dyld_image_state_mapped, 0 /* \
101 batch */, &Recorder);
102 g_initial_registration = false;
103 }
104 }
105
106 } // namespace
107
16 namespace base { 108 namespace base {
17 109
18 // static 110 // static
19 NativeLibrary LoadNativeLibrary(const base::FilePath& library_path, 111 NativeLibrary LoadNativeLibrary(const base::FilePath& library_path,
20 std::string* error) { 112 std::string* error) {
113 Initialize();
114
21 // dlopen() etc. open the file off disk. 115 // dlopen() etc. open the file off disk.
22 if (library_path.Extension() == "dylib" || 116 if (library_path.Extension() == "dylib" ||
23 !file_util::DirectoryExists(library_path)) { 117 !file_util::DirectoryExists(library_path)) {
24 void* dylib = dlopen(library_path.value().c_str(), RTLD_LAZY); 118 void* dylib = dlopen(library_path.value().c_str(), RTLD_LAZY);
25 if (!dylib) 119 if (!dylib)
26 return NULL; 120 return NULL;
27 NativeLibrary native_lib = new NativeLibraryStruct(); 121 NativeLibrary native_lib = new NativeLibraryStruct();
28 native_lib->type = DYNAMIC_LIB; 122 native_lib->type = DYNAMIC_LIB;
29 native_lib->dylib = dylib; 123 native_lib->dylib = dylib;
124 native_lib->image_path = library_path;
30 return native_lib; 125 return native_lib;
31 } 126 }
32 base::mac::ScopedCFTypeRef<CFURLRef> url( 127 base::mac::ScopedCFTypeRef<CFURLRef> url(
33 CFURLCreateFromFileSystemRepresentation( 128 CFURLCreateFromFileSystemRepresentation(
34 kCFAllocatorDefault, 129 kCFAllocatorDefault,
35 (const UInt8*)library_path.value().c_str(), 130 (const UInt8*)library_path.value().c_str(),
36 library_path.value().length(), 131 library_path.value().length(),
37 true)); 132 true));
38 if (!url) 133 if (!url)
39 return NULL; 134 return NULL;
40 CFBundleRef bundle = CFBundleCreate(kCFAllocatorDefault, url.get()); 135 CFBundleRef bundle = CFBundleCreate(kCFAllocatorDefault, url.get());
41 if (!bundle) 136 if (!bundle)
42 return NULL; 137 return NULL;
43 138
44 NativeLibrary native_lib = new NativeLibraryStruct(); 139 NativeLibrary native_lib = new NativeLibraryStruct();
45 native_lib->type = BUNDLE; 140 native_lib->type = BUNDLE;
46 native_lib->bundle = bundle; 141 native_lib->bundle = bundle;
47 native_lib->bundle_resource_ref = CFBundleOpenBundleResourceMap(bundle); 142 native_lib->bundle_resource_ref = CFBundleOpenBundleResourceMap(bundle);
143
144 base::mac::ScopedCFTypeRef<CFURLRef> executable_url(
145 CFBundleCopyExecutableURL(bundle));
146 NSURL* executable_url_ns = base::mac::CFToNSCast(executable_url);
147 native_lib->image_path =
148 base::FilePath([[executable_url_ns path] fileSystemRepresentation]);
149
48 return native_lib; 150 return native_lib;
49 } 151 }
50 152
51 // static 153 // static
52 void UnloadNativeLibrary(NativeLibrary library) { 154 void UnloadNativeLibrary(NativeLibrary library) {
53 if (library->type == BUNDLE) { 155 bool unload = true;
54 CFBundleCloseBundleResourceMap(library->bundle, 156 {
55 library->bundle_resource_ref); 157 base::AutoLock pin(*g_module_lock_.Pointer());
56 CFRelease(library->bundle); 158 unload = !g_module_set_.Pointer()->count(library->image_path.value().c_str() );
57 } else { 159 }
58 dlclose(library->dylib); 160 if (unload) {
161 if (library->type == BUNDLE) {
162 CFBundleCloseBundleResourceMap(library->bundle,
163 library->bundle_resource_ref);
164 CFRelease(library->bundle);
165 } else {
166 dlclose(library->dylib);
167 }
59 } 168 }
60 delete library; 169 delete library;
61 } 170 }
62 171
63 // static 172 // static
64 void* GetFunctionPointerFromNativeLibrary(NativeLibrary library, 173 void* GetFunctionPointerFromNativeLibrary(NativeLibrary library,
65 const char* name) { 174 const char* name) {
66 if (library->type == BUNDLE) { 175 if (library->type == BUNDLE) {
67 base::mac::ScopedCFTypeRef<CFStringRef> symbol_name( 176 base::mac::ScopedCFTypeRef<CFStringRef> symbol_name(
68 CFStringCreateWithCString(kCFAllocatorDefault, name, 177 CFStringCreateWithCString(kCFAllocatorDefault, name,
69 kCFStringEncodingUTF8)); 178 kCFStringEncodingUTF8));
70 return CFBundleGetFunctionPointerForName(library->bundle, symbol_name); 179 return CFBundleGetFunctionPointerForName(library->bundle, symbol_name);
71 } 180 }
72 return dlsym(library->dylib, name); 181 return dlsym(library->dylib, name);
73 } 182 }
74 183
75 // static 184 // static
76 string16 GetNativeLibraryName(const string16& name) { 185 string16 GetNativeLibraryName(const string16& name) {
77 return name + ASCIIToUTF16(".dylib"); 186 return name + ASCIIToUTF16(".dylib");
78 } 187 }
79 188
80 } // namespace base 189 } // namespace base
OLDNEW
« 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