Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Associated objects bugs #330

Closed
rfm opened this issue Mar 10, 2025 · 3 comments
Closed

Associated objects bugs #330

rfm opened this issue Mar 10, 2025 · 3 comments
Assignees

Comments

@rfm
Copy link
Contributor

rfm commented Mar 10, 2025

I think there are two bugs in the associated objects implementation as follows:

  1. it looks like retained/copied values are not released when the object they are associated with is deallocated, causing leaks.
  2. it looks like the atomic policy is not fully implemented ... when getting an associated value it is not retained/autoreleased, so another thread can destroy it before the calling thread gets to retain it.

These issues are demonstrated in the gnustep-base tests (marked as hopeful) in Tests/base/Functions/runtime.m
These tests pass on OSX

@hmelder hmelder self-assigned this Mar 11, 2025
@hmelder
Copy link
Collaborator

hmelder commented Mar 15, 2025

it looks like retained/copied values are not released when the object they are associated with is deallocated, causing leaks

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

static void *AssociatedObjectKey = &AssociatedObjectKey;

void testAssociatedObjectMemoryLeak() {
    __weak id weakObject;

    @autoreleasepool {
		NSObject *testObj = [NSObject new];
        NSString *associatedValue = [NSString stringWithFormat:@"TestValue %p", AssociatedObjectKey]; // Force an allocated string

        objc_setAssociatedObject(testObj, AssociatedObjectKey, associatedValue, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        weakObject = associatedValue;

        assert(weakObject != nil && "Associated object should be retained inside autoreleasepool");
    }

    // After the autoreleasepool block, testObj should be deallocated, and so should the associated object.
    assert(weakObject == nil && "Associated object should be released after the owner is deallocated");
}

int main() {
    testAssociatedObjectMemoryLeak();
    printf("Test passed: No memory leak detected.\n");
    return 0;
}

This passes on both macOS and Ubuntu 24.10 with libobjc2 master. It would be great to have a minimal test case to reproduce this.

@hmelder
Copy link
Collaborator

hmelder commented Mar 15, 2025

These issues are demonstrated in the gnustep-base tests (marked as hopeful) in Tests/base/Functions/runtime.m

Ah nvm

@hmelder
Copy link
Collaborator

hmelder commented Mar 15, 2025

All tests in runtime.m pass with this PR #331. Behaviour is now aligned with Apple's objc4.

@hmelder hmelder closed this as completed Mar 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants