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 BOOL hasName(const char * const *names, const char *query)
30 while ((name = *names++)) {
31 if (strstr(name, query)) return YES;
41 unsigned int imageCount, imageCount0;
45 names = objc_copyImageNames(&imageCount0);
49 void *bundle = dlopen("unload2.bundle", RTLD_LAZY);
52 names = objc_copyImageNames(&imageCount);
54 testassert(imageCount == imageCount0 + 1);
55 testassert(hasName(names, "unload2.bundle"));
58 Class small = objc_getClass("SmallClass");
59 Class big = objc_getClass("BigClass");
63 name = class_getImageName(small);
65 testassert(strstr(name, "unload2.bundle"));
66 name = class_getImageName(big);
68 testassert(strstr(name, "unload2.bundle"));
75 // give BigClass and BigClass->isa large method caches (4692641)
76 for (i = 0; i < 10000; i++) {
77 sprintf(buf, "method_%d", i);
78 SEL sel = sel_registerName(buf);
79 ((void(*)(id, SEL))objc_msgSend)(o2, sel);
80 ((void(*)(id, SEL))objc_msgSend)(object_getClass(o2), sel);
88 int err = dlclose(bundle);
90 err = dlclose(bundle);
91 testassert(err == -1); // already closed
93 testassert(objc_getClass("SmallClass") == NULL);
94 testassert(objc_getClass("BigClass") == NULL);
96 names = objc_copyImageNames(&imageCount);
98 testassert(imageCount == imageCount0);
99 testassert(! hasName(names, "unload2.bundle"));
102 // these selectors came from the bundle
103 testassert(0 == strcmp("unload2_instance_method", sel_getName(sel_registerName("unload2_instance_method"))));
104 testassert(0 == strcmp("unload2_category_method", sel_getName(sel_registerName("unload2_category_method"))));
109 // fixme object_dispose() not aggressive enough?
110 if (objc_collectingEnabled()) succeed(__FILE__);
115 int count = is_guardmalloc() ? 10 : 100;
120 // fixme heap use goes up 512 bytes after the 2nd cycle only - bad or not?
129 testwarn("rdar://11369189 can't check leaks because libxpc leaks");
131 // 5359412 Make sure dylibs with nothing other than image_info can close
132 void *dylib = dlopen("unload3.dylib", RTLD_LAZY);
134 int err = dlclose(dylib);
135 testassert(err == 0);
136 err = dlclose(dylib);
137 testassert(err == -1); // already closed
139 // Make sure dylibs with real objc content cannot close
140 dylib = dlopen("unload4.dylib", RTLD_LAZY);
142 err = dlclose(dylib);
143 testassert(err == 0);
144 err = dlclose(dylib);
145 testassert(err == 0); // dlopen from libobjc itself
146 err = dlclose(dylib);
147 testassert(err == -1); // already closed