3 $C{COMPILE} $DIR/unload4.m -o unload4.dylib -dynamiclib
4 $C{COMPILE_C} $DIR/unload3.c -o unload3.dylib -dynamiclib
5 $C{COMPILE} $DIR/unload2.m -o unload2.bundle -bundle
6 $C{COMPILE} $DIR/unload.m -o unload.out
11 #include <objc/runtime.h>
17 #if __has_feature(objc_arc)
21 testwarn("rdar://11368528 confused by Foundation");
27 static id forward_handler(void)
32 static BOOL hasName(const char * const *names, const char *query)
35 while ((name = *names++)) {
36 if (strstr(name, query)) return YES;
46 unsigned int imageCount, imageCount0;
50 names = objc_copyImageNames(&imageCount0);
54 void *bundle = dlopen("unload2.bundle", RTLD_LAZY);
57 names = objc_copyImageNames(&imageCount);
59 testassert(imageCount == imageCount0 + 1);
60 testassert(hasName(names, "unload2.bundle"));
63 Class small = objc_getClass("SmallClass");
64 Class big = objc_getClass("BigClass");
68 name = class_getImageName(small);
70 testassert(strstr(name, "unload2.bundle"));
71 name = class_getImageName(big);
73 testassert(strstr(name, "unload2.bundle"));
80 // give BigClass and BigClass->isa large method caches (4692641)
81 for (i = 0; i < 10000; i++) {
82 sprintf(buf, "method_%d", i);
83 SEL sel = sel_registerName(buf);
84 ((void(*)(id, SEL))objc_msgSend)(o2, sel);
85 ((void(*)(id, SEL))objc_msgSend)(object_getClass(o2), sel);
93 int err = dlclose(bundle);
95 err = dlclose(bundle);
96 testassert(err == -1); // already closed
98 testassert(objc_getClass("SmallClass") == NULL);
99 testassert(objc_getClass("BigClass") == NULL);
101 names = objc_copyImageNames(&imageCount);
103 testassert(imageCount == imageCount0);
104 testassert(! hasName(names, "unload2.bundle"));
107 // these selectors came from the bundle
108 testassert(0 == strcmp("unload2_instance_method", sel_getName(sel_registerName("unload2_instance_method"))));
109 testassert(0 == strcmp("unload2_category_method", sel_getName(sel_registerName("unload2_category_method"))));
114 // fixme object_dispose() not aggressive enough?
115 if (objc_collectingEnabled()) succeed(__FILE__);
117 objc_setForwardHandler((void*)&forward_handler, (void*)&forward_handler);
122 int count = is_guardmalloc() ? 10 : 100;
127 // fixme heap use goes up 512 bytes after the 2nd cycle only - bad or not?
137 // 5359412 Make sure dylibs with nothing other than image_info can close
138 void *dylib = dlopen("unload3.dylib", RTLD_LAZY);
140 int err = dlclose(dylib);
141 testassert(err == 0);
142 err = dlclose(dylib);
143 testassert(err == -1); // already closed
145 // Make sure dylibs with real objc content cannot close
146 dylib = dlopen("unload4.dylib", RTLD_LAZY);
148 err = dlclose(dylib);
149 testassert(err == 0);
150 err = dlclose(dylib);
151 testassert(err == 0); // dlopen from libobjc itself
152 err = dlclose(dylib);
153 testassert(err == -1); // already closed