methodCacheLeaks.m 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  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. #include "test.h"
  8. #include "testroot.i"
  9. #include <spawn.h>
  10. #include <stdio.h>
  11. void noopIMP(id self __unused, SEL _cmd __unused) {}
  12. id test(int n, int methodCount) {
  13. char *name;
  14. asprintf(&name, "TestClass%d", n);
  15. Class c = objc_allocateClassPair([TestRoot class], name, 0);
  16. free(name);
  17. SEL *sels = malloc(methodCount * sizeof(*sels));
  18. for(int i = 0; i < methodCount; i++) {
  19. asprintf(&name, "selector%d", i);
  20. sels[i] = sel_getUid(name);
  21. free(name);
  22. }
  23. for(int i = 0; i < methodCount; i++) {
  24. class_addMethod(c, sels[i], (IMP)noopIMP, "v@:");
  25. }
  26. objc_registerClassPair(c);
  27. id obj = [[c alloc] init];
  28. for (int i = 0; i < methodCount; i++) {
  29. ((void (*)(id, SEL))objc_msgSend)(obj, sels[i]);
  30. }
  31. free(sels);
  32. return obj;
  33. }
  34. int main()
  35. {
  36. int classCount = 16;
  37. id *objs = malloc(classCount * sizeof(*objs));
  38. for (int i = 0; i < classCount; i++) {
  39. objs[i] = test(i, 1 << i);
  40. }
  41. char *pidstr;
  42. int result = asprintf(&pidstr, "%u", getpid());
  43. testassert(result);
  44. extern char **environ;
  45. char *argv[] = { "/usr/bin/leaks", pidstr, NULL };
  46. pid_t pid;
  47. result = posix_spawn(&pid, "/usr/bin/leaks", NULL, NULL, argv, environ);
  48. if (result) {
  49. perror("posix_spawn");
  50. exit(1);
  51. }
  52. wait4(pid, NULL, 0, NULL);
  53. printf("objs=%p\n", objs);
  54. }