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

Mocks crashing due to relative addressing #440

Open
dmaclach opened this issue Jun 29, 2020 · 2 comments
Open

Mocks crashing due to relative addressing #440

dmaclach opened this issue Jun 29, 2020 · 2 comments

Comments

@dmaclach
Copy link
Contributor

- (void)testMockView {
  UIViewController *controller = [[UIViewController alloc] init];
  UIViewController *controller2 = [[UIViewController alloc] init];
  id mockController2 = OCMPartialMock(controller2);
  [controller addChildViewController:mockController2];
}

will crash with libGuardMalloc turned on. I'm guessing that the problem is that addChildViewController: is directly instance variables with its knowledge of UIViewController using offsets relative to self which in this case is a mock and not the controller itself. This ends up being a weird looking crash that is a pain to diagnose, and could end up "working" but corrupting the heap in weird and wonderful ways.

The problem can be avoided by not passing in the mock object. Should we be issuing a warning where partial mocks are being used instead of the object that they are mocking (I'm thinking -[OCMPartialMockObject handleUnRecordedInvocation:])

@dmaclach
Copy link
Contributor Author

BTW I forgot to mention that this is an issue with 3.6 as well as head.

@dmaclach dmaclach changed the title Partial mocks crashing due to relative addressing Mocks crashing due to relative addressing Jun 30, 2020
@dmaclach
Copy link
Contributor Author

So here's an example that removes UIViewController and shows that this is not just a partial mock issue:

@interface TestClassLargeClass : NSObject {
  int foo[4096];
}
@end

@implementation TestClassLargeClass

- (void)messWithClass:(TestClassLargeClass *)cls
{
  for(int i = 0; i < 4096; ++i) {
    cls->foo[i] = i;
  }
}

@end

...

- (void)testClassLargeClass {
  TestClassLargeClass *one = [[TestClassLargeClass alloc] init];
  id mocktwo = OCMClassMock([TestClassLargeClass class]);
  [one messWithClass:mocktwo];
}

It can happen with any class that knows the internals of another. It's pretty nasty actually because it can cause very subtle memory corruption that shows up later in other tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants