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

EXC_BAD_ACCESS during autocapture of layer borderColor #226

Closed
jadar opened this issue Oct 31, 2024 · 11 comments
Closed

EXC_BAD_ACCESS during autocapture of layer borderColor #226

jadar opened this issue Oct 31, 2024 · 11 comments
Assignees
Labels
bug Something isn't working Session Replay

Comments

@jadar
Copy link

jadar commented Oct 31, 2024

Version

3.13.3

Steps to Reproduce

  1. Create an interface with a Storyboard. Add a UIButton and properties to set the layer.borderColor in the Storyboard file.
  2. Enable PostHog session replay
  3. Navigate to screen and observe crash

Expected Result

No crash

Actual Result

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x194b96cec)
  * frame #0: 0x0000000194b96cec libswiftCore.dylib`swift::hashable_support::findHashableBaseType(swift::TargetMetadata<swift::InProcess> const*) (.cold.1) + 16
    frame #1: 0x0000000194adfaa8 libswiftCore.dylib`swift_slowAlloc + 100
    frame #2: 0x0000000194adfd54 libswiftCore.dylib`swift_allocObject + 52
    frame #3: 0x000000018b208af8 CoreGraphics`___lldb_unnamed_symbol19785 + 64
    frame #4: 0x000000018b206a28 CoreGraphics`__C.CGColorRef.components.getter : Swift.Optional<Swift.Array<CoreGraphics.CGFloat>> + 48
    frame #5: 0x00000001065aca4c App.debug.dylib`CGColorRef.toRGBString() at CGColor+Util.swift:15:36
    frame #6: 0x00000001065b7afc App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x0000000107741870) at PostHogReplayIntegration.swift:461:52
    frame #7: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x0000000107741090) at PostHogReplayIntegration.swift:468:36
    frame #8: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x0000000107742cb0) at PostHogReplayIntegration.swift:468:36
    frame #9: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x0000000107742b20) at PostHogReplayIntegration.swift:468:36
    frame #10: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x00000001079af950) at PostHogReplayIntegration.swift:468:36
    frame #11: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x00000001079a80c0) at PostHogReplayIntegration.swift:468:36
    frame #12: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x00000001079becf0) at PostHogReplayIntegration.swift:468:36
    frame #13: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x00000001079b6c20) at PostHogReplayIntegration.swift:468:36
    frame #14: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x00000001079386e0) at PostHogReplayIntegration.swift:468:36
    frame #15: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x0000000107999d70) at PostHogReplayIntegration.swift:468:36
    frame #16: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x000000010792fe30) at PostHogReplayIntegration.swift:468:36
    frame #17: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x000000010790cb30) at PostHogReplayIntegration.swift:468:36
    frame #18: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x000000010770f6b0) at PostHogReplayIntegration.swift:468:36
    frame #19: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x0000000107908b40) at PostHogReplayIntegration.swift:468:36
    frame #20: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x0000000107909750) at PostHogReplayIntegration.swift:468:36
    frame #21: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x0000000107909000) at PostHogReplayIntegration.swift:468:36
    frame #22: 0x00000001065b7cb0 App.debug.dylib`PostHogReplayIntegration.toWireframe(view=0x00000001076127c0) at PostHogReplayIntegration.swift:468:36
    frame #23: 0x00000001065b27b8 App.debug.dylib`PostHogReplayIntegration.generateSnapshot(view=0x00000001076127c0, screenName="Initial") at PostHogReplayIntegration.swift:87:109
Screenshot 2024-10-31 at 5 09 08 PM Screenshot 2024-10-31 at 5 09 41 PM
@jadar jadar added the bug Something isn't working label Oct 31, 2024
@ioannisj
Copy link
Contributor

ioannisj commented Nov 1, 2024

Hey @jadar! Thanx for reporting this.

I'll take a look. From the screenshot, it seems you are assigning a named color from an asset catalog or color set. Could you confirm if there are any specific settings adjusted in the Attribute Inspector? My initial thought is that the color may is not RGB scale (grayscale?) and we may not handle that case correctly.

In the meantime, you might try enabling screenshot mode to bypass this issue temporarily.
Screenshot mode can be enabled with config.sessionReplayConfig.screenshotMode = true

@marandaneto
Copy link
Member

@ioannisj would a simple try/catch here works as a quick win?

@ioannisj
Copy link
Contributor

ioannisj commented Nov 1, 2024

@ioannisj would a simple try/catch here works as a quick win?

No, I don't think so since there are no throwing functions involved here.

@ioannisj ioannisj self-assigned this Nov 1, 2024
@marandaneto
Copy link
Member

@ioannisj I think you can do this:

        // Ensure the color is in an RGB color space
        guard let colorSpace = CGColorSpace(name: CGColorSpace.sRGB),
              let rgbColor = self.converted(to: colorSpace, intent: .defaultIntent, options: nil),
              let components = rgbColor.components, components.count >= 3 else {
            return nil
        }

Can you validate if that would help?

@ioannisj
Copy link
Contributor

ioannisj commented Nov 4, 2024

Managed to recreate this with the following. I'll see if there is a safe way to convert to sRGB, otherwise I'll just add the check there

CleanShot 2024-11-04 at 13 07 38@2x
CleanShot 2024-11-04 at 13 07 50@2x
CleanShot 2024-11-04 at 13 09 51@2x

@ioannisj
Copy link
Contributor

ioannisj commented Nov 4, 2024

Digging a bit deeper on this one, it seems that the real underlying issue is not the color space (since we were safe with the components.count >= 3 part) but the fact that all named/dynamic colors from the interface builder get their true values set after viewDidLoad. I imagine this is because the view needs to be fully loaded to check the traits before assigning a dark or light variant.

Adding the RGB check will only handle the cases where the dynamic color happens to be gray scale (and it's an additional check other that components.count which won't crash), but that's not the ultimate reason for the crash 🤔
Changing the dynamic color to RGB range will again crash the app when components is accessed.

Printing out layer.borderColor.numberOfComponents prints out some random values like 105553118884896 which is an indication that we are dealing with an uninitialized instance of CGColor from unmanaged code that points to a random memory address

@jadar
Copy link
Author

jadar commented Nov 4, 2024

@ioannisj

I'll take a look. From the screenshot, it seems you are assigning a named color from an asset catalog or color set. Could you confirm if there are any specific settings adjusted in the Attribute Inspector?

You're correct that the color comes from an asset catalog. The settings are sRGB with a hexadecimal value of #676767, with 100% opacity. Here's the full contents:

ButtonTitleGray.colorset/Contents.json
{
  "colors" : [
    {
      "color" : {
        "color-space" : "srgb",
        "components" : {
          "alpha" : "1.000",
          "blue" : "0x67",
          "green" : "0x67",
          "red" : "0x67"
        }
      },
      "idiom" : "universal"
    },
    {
      "appearances" : [
        {
          "appearance" : "luminosity",
          "value" : "dark"
        }
      ],
      "color" : {
        "color-space" : "srgb",
        "components" : {
          "alpha" : "1.000",
          "blue" : "1.000",
          "green" : "1.000",
          "red" : "1.000"
        }
      },
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}

In the meantime, you might try enabling screenshot mode to bypass this issue temporarily.
Screenshot mode can be enabled with config.sessionReplayConfig.screenshotMode = true

I did end up using this workaround as well. I removed references to the custom color in the project, which allowed it to function without crashing. However, the default session capture did not function properly at all, as nothing was distinguishable in the capture.

@ioannisj
Copy link
Contributor

ioannisj commented Nov 4, 2024

However, the default session capture did not function properly at all, as nothing was distinguishable in the capture.

Are you referring here to the session recording having some blacked out content. You can try experimenting with maskAllTextInputs and maskAllImage to see if this here. docs

A temporary fix on the crash should be out soon btw, I'll let you know once it's out. Hope that helps

@jadar
Copy link
Author

jadar commented Nov 4, 2024

@ioannisj

Are you referring here to the session recording having some blacked out content. You can try experimenting with maskAllTextInputs and maskAllImage to see if this here. docs

It's a little out of the scope of this issue, and I don't know what exactly was the issue, but it appeared all the UI elements were clustered in the top left part of the screen.

@ioannisj
Copy link
Contributor

ioannisj commented Nov 5, 2024

Hey @jadar, fyi fix for this bug has been release with 3.14.0

Regarding the session recording issue, can you please open a bug report when you get a chance with some screenshots? I have a feeling you are describing an issue with wireframe mode and not screenshot mode.

@ioannisj ioannisj closed this as completed Nov 5, 2024
@jadar
Copy link
Author

jadar commented Nov 5, 2024

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Session Replay
Projects
None yet
Development

No branches or pull requests

3 participants