]> git.saurik.com Git - apple/objc4.git/blob - test/methodCacheLeaks.m
objc4-818.2.tar.gz
[apple/objc4.git] / test / methodCacheLeaks.m
1 // TEST_CONFIG MEM=mrc LANGUAGE=objective-c
2 /*
3 TEST_RUN_OUTPUT
4 [\S\s]*0 leaks for 0 total leaked bytes[\S\s]*
5 END
6 */
7
8 #include "test.h"
9 #include "testroot.i"
10
11 #include <spawn.h>
12 #include <stdio.h>
13
14 void noopIMP(id self __unused, SEL _cmd __unused) {}
15
16 id test(int n, int methodCount) {
17 char *name;
18 asprintf(&name, "TestClass%d", n);
19 Class c = objc_allocateClassPair([TestRoot class], name, 0);
20 free(name);
21
22 SEL *sels = malloc(methodCount * sizeof(*sels));
23 for(int i = 0; i < methodCount; i++) {
24 asprintf(&name, "selector%d", i);
25 sels[i] = sel_getUid(name);
26 free(name);
27 }
28
29 for(int i = 0; i < methodCount; i++) {
30 class_addMethod(c, sels[i], (IMP)noopIMP, "v@:");
31 }
32
33 objc_registerClassPair(c);
34
35 id obj = [[c alloc] init];
36 for (int i = 0; i < methodCount; i++) {
37 ((void (*)(id, SEL))objc_msgSend)(obj, sels[i]);
38 }
39 free(sels);
40 return obj;
41 }
42
43 int main()
44 {
45 int classCount = 16;
46 id *objs = malloc(classCount * sizeof(*objs));
47 for (int i = 0; i < classCount; i++) {
48 objs[i] = test(i, 1 << i);
49 }
50
51 char *pidstr;
52 int result = asprintf(&pidstr, "%u", getpid());
53 testassert(result);
54
55 extern char **environ;
56 char *argv[] = { "/usr/bin/leaks", pidstr, NULL };
57 pid_t pid;
58 result = posix_spawn(&pid, "/usr/bin/leaks", NULL, NULL, argv, environ);
59 if (result) {
60 perror("posix_spawn");
61 exit(1);
62 }
63 wait4(pid, NULL, 0, NULL);
64
65 // Clean up. Otherwise leaks can end up seeing this as a leak, oddly enough.
66 for (int i = 0; i < classCount; i++) {
67 [objs[i] release];
68 }
69 free(objs);
70 }