"Object was retained too many times"

Thanks for the report! The limit is 2^31, which ought to be highly unlikely for any object to reach in normal circumstances. It's likely that we have a compiler bug causing an unbalanced retain that accretes over time until the limit is hit.

To track down what object is triggering the overflow, you might be able to hook into swift_retain so that it raises an alert when an object exceeds a lower threshold, like 1000 or something. There are global variables containing function pointers to the retain/release implementation that you can reassign to hook the operations, so maybe you can do something like this in a C file you mix into your Swift project:

extern void *(*_swift_retain)(void *);

static void *(*_old_swift_retain)(void*);

size_t swift_retainCount(void *);

static void *swift_retain_hook(void *object) {
  if (swift_retainCount(object) > 1000)
    fprintf(stderr, "object at %p has 1000 retains!", object);
  return _old_swift_retain(object);
}

__attribute__((constructor))
static void hook_swift_retain() {
  _old_swift_retain = _swift_retain;
  _swift_retain = swift_retain_hook;
}
11 Likes