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

Crash using Nimble 5.0.0 & OCMock 3.3.1 #377

Closed
modocache opened this issue Dec 14, 2016 · 18 comments
Closed

Crash using Nimble 5.0.0 & OCMock 3.3.1 #377

modocache opened this issue Dec 14, 2016 · 18 comments
Labels

Comments

@modocache
Copy link
Member

Migrating erikdoe/ocmock#319 here. I couldn't quite figure it out, but it seems like Nimble was failing to print a description of an OCClassMockObject.

@modocache modocache added the bug label Dec 14, 2016
@ikesyo
Copy link
Member

ikesyo commented Dec 14, 2016

Maybe we should have a special handling for NSProxy?

description of NSObjectProtocol, which will be the counterpart of Swift's CustomStringConvertible is implemented on NSProxy. On the other hand, debugDescription of NSObjectProtocol, which may mean CustomDebugStringConvertible in Swift is an optional property and will not be implemented on NSProxy.

@jeffh
Copy link
Member

jeffh commented Dec 14, 2016 via email

@joeljfischer
Copy link

Hello everyone, this still appears to be open, and unfortunately many of our unit tests are broken on the latest releases of Quick / Nimble. Has there been any further movement on this issue?

@modocache
Copy link
Member Author

As @ikesyo pointed out, this seems like something that could be fixed by modifying Nimble's stringify function to handle NSProxy. I think adding an if let value = value as? NSProxy { ... } statement to handle this case should do the trick.

@joeljfischer, would you be willing to submit a pull request for that case? Since you have a test suite that demonstrates the problem, I think you'd be able to quickly iterate on the solution.

@joeljfischer
Copy link

Sure, I'll try to take a look today.

@joeljfischer
Copy link

joeljfischer commented Jan 11, 2017

I spent some time on this, and I repeatedly got the error until I turned off optimization on the Nimble project and rebuilt, then everything seems to work correctly. Any ideas on why that might be? Swift's debugging capabilities still kind of suck so it's hard to tell exactly what's going on.

@modocache
Copy link
Member Author

Awesome, thanks for working on this! A few questions that could help me figure out what's going wrong here:

  • You mention an error -- are you referring to the crash this issue is in reference to?
  • Do you mean that, without any modifications, turning off optimizations when building Nimble caused the crash to stop occurring? Or, if you made some modifications, could you post the diff here?

@joeljfischer
Copy link

  1. Yes, I was referring to the crash referenced in this issue.
  2. That's correct. With no modifications, by turning off optimizations (so that I could debug more easily) the crash disappeared.

@modocache
Copy link
Member Author

Hmm, that's definitely interesting. My understanding is that program behavior should never change due to optimization level, just the speed at which the program executes. Changes in behavior seem like a bug in the compiler or runtime.

Still, since finding a workaround here is probably the first step to diagnosing any compiler bugs anyway, let's start there. If it were me, I'd switch back to an optimized build and try to find a workaround that prevents the crash from happening. I still think the NSProxy theory is a strong one, so I'd add the if statement I mention a few comments above and see what happens.

@joeljfischer
Copy link

I did attempt that first and it did not seem to help, but with the optimized build I wasn't able to step through to actually see what was happening. No breakpoints I set into the stringify function would actually fire, and the error would always fire on the return stringify(unboxed) line, which didn't help since it was likely failing in the unwrapped stringify method.

@modocache
Copy link
Member Author

Yeah, I suppose a debugger won't work because it's optimized. I'd probably switch to print-based debugging at this point (a tool of the pros).

@jeffh
Copy link
Member

jeffh commented Jan 18, 2017

Do you have a small sample project that can reproduce it? I did some native NSProxy implementations that didn't seem to cause any problems. I guess next time I get a chance I'll try with OCMock.

@joeljfischer
Copy link

I wasn't able to get a small sample project that will reproduce it, but I pushed a branch of the primary project that has been showing the issue: https://github.com/smartdevicelink/sdl_ios/tree/hotfix/nimble_fix_tests

You'd just have to pull in the libraries with carthage and run the tests.

@joeljfischer
Copy link

Using print statements, this is what I'm seeing.

I changed the relevant Nimble code to:

public func stringify<T>(_ value: T) -> String {
    print("Stringify: \(value)")

    if let value = value as? TestOutputStringConvertible {
        print("TestOutputStringConvertible")
        return value.testDescription
    }
    
    if let value = value as? CustomDebugStringConvertible {
        print("CustomDebugStringConvertible")
        return value.debugDescription
    }

    print("None of those, describing...")
    return String(describing: value)
}

/// -SeeAlso: `stringify<T>(value: T)`
public func stringify<T>(_ value: T?) -> String {
    print("Stringify? \(value)")
    if let unboxed = value {
        return stringify(unboxed)
    }
    return "nil"
}

and this is the output

Stringify? Optional(<SDLConfiguration: 0x7ff562635390>)
Stringify: <SDLConfiguration: 0x7ff562635390>
CustomDebugStringConvertible
Stringify? Optional(<SDLConfiguration: 0x7ff562635390>)
Stringify: <SDLConfiguration: 0x7ff562635390>
CustomDebugStringConvertible
Stringify? Optional(OCProtocolMockObject)
Stringify: OCProtocolMockObject
Could not cast value of type 'OCProtocolMockObject' (0x1164fc108) to 'Swift.CustomDebugStringConvertible' (0x1164390e8).

It's very interesting that it's saying it can't convert to a CustomDebugStringConvertible yet the print statement within that if let isn't firing. That makes me think something weird is going on on the cast in the if let itself.

@jeffh
Copy link
Member

jeffh commented Jan 21, 2017

Interesting, it seems like the Swift compiler chooses to convert the instance to it's corresponding class. It might seem that Swift accidentally interprets the pointer as a class.

@joeljfischer
Copy link

I'm starting to break out into a cold sweat with the announcement that Xcode 8.3 will drop Swift 2.3 support. Once that happens, I won't have functioning tests. Any further ideas on a possible fix? I'll take another look soon.

@joeljfischer
Copy link

Just wanted to note that now that Xcode 8.3 is out, we've had to disable all of our tests using OCMock. I'm not sure if there's any further thoughts on working around this bug, or if we're going to have to rethink how we do those tests.

@ikesyo
Copy link
Member

ikesyo commented Aug 7, 2018

Closing this due to inactivity.

@ikesyo ikesyo closed this as completed Aug 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants