lwouis / alt-tab-macos

Windows alt-tab on macOS
https://alt-tab-macos.netlify.app
GNU General Public License v3.0
10.42k stars 317 forks source link

Crashes after the screen is locked for a while #3253

Open Blendertom opened 5 months ago

Blendertom commented 5 months ago

Describe the bug Alttab crashes while the screen is locked.

Steps to reproduce the bug Lock the device, be away for a half an hour, unlock the device, try to use CMD+Tab, and there's no response. There's no crash report popup either.

Your environment

lwouis commented 5 months ago

Hi,

From the log file, it seems that something went wrong while loading the NIB file for the menu. Relevant stacktrace:

{"thread_create":0,"thread_set_state":0,"task_for_pid":0},"targeted":{"thread_create":0,"thread_set_state":0,"task_for_pid":0},"warnings":0},
  "lastExceptionBacktrace" : [{"imageOffset":992564,"symbol":"__exceptionPreprocess","symbolLocation":164,"imageIndex":11},{"imageOffset":106164,"symbol":"objc_exception_throw","symbolLocation":60,"imageIndex":12},{"imageOffset":992304,"symbol":"+[NSException exceptionWithName:reason:userInfo:]","symbolLocation":0,"imageIndex":11},{"imageOffset":416708,"symbol":"UINibDecoderDecodeObjectForValue","symbolLocation":760,"imageIndex":20},{"imageOffset":417008,"symbol":"UINibDecoderDecodeObjectForValue","symbolLocation":1060,"imageIndex":20},{"imageOffset":415924,"symbol":"-[UINibDecoder decodeObjectForKey:]","symbolLocation":312,"imageIndex":20},{"imageOffset":73228,"symbol":"-[NSIBObjectData initWithCoder:]","symbolLocation":160,"imageIndex":16},{"imageOffset":416616,"symbol":"UINibDecoderDecodeObjectForValue","symbolLocation":668,"imageIndex":20},{"imageOffset":415924,"symbol":"-[UINibDecoder decodeObjectForKey:]","symbolLocation":312,"imageIndex":20},{"imageOffset":72716,"symbol":"loadNib","symbolLocation":264,"imageIndex":16},{"imageOffset":70280,"symbol":"+[NSBundle(NSNibLoading) _loadNibFile:nameTable:options:withZone:ownerBundle:]","symbolLocation":560,"imageIndex":16},{"imageOffset":69516,"symbol":"-[NSBundle(NSNibLoading) loadNibNamed:owner:topLevelObjects:]","symbolLocation":180,"imageIndex":16},{"imageOffset":205620,"symbol":"App.loadMainMenuXib()","symbolLocation":172,"imageIndex":7},{"imageOffset":203072,"symbol":"closure #1 in App.applicationDidFinishLaunching(_:)","symbolLocation":428,"imageIndex":7},{"imageOffset":130472,"symbol":"closure #1 in static SystemPermissions.ensurePermissionsAreGranted(_:)","symbolLocation":40,"imageIndex":7},{"imageOffset":130048,"symbol":"closure #1 in closure #1 in static SystemPermissions.observePermissionsPreStartup(_:)","symbolLocation":152,"imageIndex":7},{"imageOffset":180284,"symbol":"thunk for @escaping @callee_guaranteed () -> ()","symbolLocation":28,"imageIndex":7},

I'm not sure what we can do about it. The code crashes within Apple framework (i.e. UINibDecoderDecodeObjectForValue), not within the app code.

Something I don't understand is why the app would load the menu when you unlock the screen. The app should load the menu initially. Technically, it does so after the app is launched, and after the system permissions are granted by the user. After that, it shouldn't be called again. However, you say that you locked your screen, then come back and it was crashed. This is surprising because locking the screen doesn't affect apps. They still run behind the screen lock.

Are you sure that this crash log is from the app crashing when the screen was locked?

Thank you 🙇

Blendertom commented 5 months ago

Just happened again. I had the screen locked and I was away for a while (1.5 hours), came back and tried to use Alttab, and turns out it'd crashed.

Before going away, I'd reset my alttab preferences (and changed shortcut to CMD+tab), I did get alttab's dialog asking me to send the crash report to you.

This is the log from this crash the timestamp suggests that the crashed happed just as I unlocked the screen, or when I woke the macbook but hadn't unlocked it yet.

When you say:

Something I don't understand is why the app would load the menu when you unlock the screen.

Are you referring to the menubar? If so, I have bartender installed with Alttab's icon always hidden. Could this be related? I plan on being away from the laptop soon, for more than an hour, I can quit bartender before leaving, to see if that helps.

lwouis commented 5 months ago

Thanks a lot for the clear and comprehensive message!

The Bartender hypothesis is interesting. However, I just tested with Bartender v5.0.49, hidding AltTab icon, and locking my screen. Nothing crashed, and the app didn't load the menubar either.

2 things:

I'm not sure how to investigate this better. I can't reproduce locally. I don't see how the code to load the menubar actions would load after a screen lock/unlock. It's only loads on app launch normally. That's what I see locally as well.

Any idea ? Thank you 🙇

Blendertom commented 5 months ago

Just came back. Unfortunately, I forgot to quit bartender before leaving. Here's the crashlog.

I was away from my laptop again for 10 mins, but this time no bartender. Alttab did not crash - but that might now mean much as the crash happens when the laptop has been locked for at least 30 mins.

Can you confirm if you're on Apple silicon and have SIP disabled?

lwouis commented 5 months ago

Yes, I'm on an M2 macbook pro. I have SIP enabled.

If it's about leaving the mac locked for a long time, maybe it could be something about app termination. That the OS, or some third-party app you have would kill and restart AltTab, and somehow that process makes the menubar loading crash?

I just tried launching AltTab and quickly launching the screen lock. AltTab launches correctly even though it's behind the locked screen. I don't see how it would fail to load the menubar.

I'm struggling to picturing the process that leads to the menubar loading while the screen is locked. There are no user actions. Why would the OS mess with open apps at this point?

Blendertom commented 5 months ago

If it's about leaving the mac locked for a long time, maybe it could be something about app termination. That the OS, or some third-party app you have would kill and restart AltTab, and somehow that process makes the menubar loading crash?

That's possible - I don't think I have anything installed or configured to do that. But I'll review what I've messed around with.

Blendertom commented 5 months ago

Not sure if this is relevant or not, just now as I unlocked my screen, I saw AltTab's permission pop up for a spilt second (the one where it guides you to give AltTab the screen recording and accessibility permissions), and then it crashed.

So the crash is happening moments after the screen is unlocked. AltTab-2024-03-22-104553.txt

I'd bartender closed this time.

I've enable SIP, just to remove variables.

lwouis commented 5 months ago

In the crash logs I see that it crashed in the observePermissionsPreStartup method, which is called at launch, only if the permissions are not granted. This is corroborated by the fact that you saw the permission window show up shortly.

There are 2 things I don't understand:

I see in the crash logs that AltTab was launched by launchd. This means that it was a "start at login" launch, and not a manual launch from you.

Could you please show me the results of running this command? cat ~/Library/LaunchAgents/com.lwouis.alt-tab-macos.plist

Also, could you please show a screenshot of what you have in System Settings > Login Items? I'm wondering if you have AltTab perhaps both in the Open at Login top section, and in the Allow in the Background section underneath?

Regarding permissions, can you confirm that they are granted? Do you have something that could mess with them? Antivirus, security software (e.g. LittleSnitch), company fleet management (e.g. jamf)?

Thank you

Blendertom commented 5 months ago

From the command:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>AssociatedBundleIdentifiers</key>
    <string>com.lwouis.alt-tab-macos</string>
    <key>Label</key>
    <string>com.lwouis.alt-tab-macos</string>
    <key>LegacyTimers</key>
    <true/>
    <key>LimitLoadToSessionType</key>
    <string>Aqua</string>
    <key>ProcessType</key>
    <string>Interactive</string>
    <key>Program</key>
    <string>/Applications/AltTab.app/Contents/MacOS/AltTab</string>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

The login items CleanShot 2024-03-22 at 14 16 18@2x

Interesting Alttab isn't in the start at login, but it is enabled in the alttab setting, and it does launch at login.

CleanShot 2024-03-22 at 14 20 10@2x

Permissions are granted, I've been seeing the permission screen since day 1, with only the second permission (I don't remember which one it is) shown as not granted, and it would only show for a second and disappear (I assume either because alttab would crash, or realises that it does have permissions).

I had Avast antivirus installed a while back, for a year, but I no longer have it installed.

lwouis commented 5 months ago

I have a hypothesis finally! Here's the scenario I could imagine:

Why is the second step happening? If the permissions are granted, why would AltTab think they are not? The issue is that there is no API to check that permission reliably. Thus, we use a workaround:

private static func screenRecordingIsGranted_() -> Bool {
        return CGDisplayStream(
            dispatchQueueDisplay: CGMainDisplayID(),
            outputWidth: 1,
            outputHeight: 1,
            pixelFormat: Int32(kCVPixelFormatType_32BGRA),
            properties: nil,
            queue: .global(),
            handler: { _, _, _, _ in }
        ) != nil
    }

This checks that we can record the screen on a 1x1 pixel squad. It's an indirect way to check if we have the right permissions. It's indirect though, and I could imagine that for some reason, as you lock/unlock the screen, this check may fail, not because the permissions are not granted, but because maybe for a few seconds, the screens are not recordable?

It turns out I had noted that possibility a few years ago.

I'm not sure how to improve the situation. There may be a better technique to guess the permission state. I remember spending a lot of time testing alternatives back then. Other apps were not doing better either, back then. I had looked at lots of open source apps to see what the state of art was.

lwouis commented 5 months ago

I just tested this more on my setup. I printed the permissions every 1ms while I:

I never got an issue where the permission was checked as false. It was always correctly read as true. I wonder was causes it in your case that the CGDisplayStream call would return nil for a short time.

Blendertom commented 4 months ago

I enabled SIP, locked my screen, and I was away for over an hour, came back and Alttab was still running.

I don't think disabling SIP did the trick, I probably had something running that needed SIP disabled, which caused the crash.

CzBiX commented 3 months ago

Hi, I ran into the same problem and this has been bothering me for a long time. I just realized today to look at the crash logs and found that I have the exact same backtrace, and sometime I saw the permissions popup a flash too. I'm not sure of the exact timing of the crash. since I only noticed it wasn't working when Im using cmd+tab after unlocked .

I'm using macOS 14.4.1 with SIP enabled, and 1 external display connected when internal display is disabled.

CzBiX commented 3 months ago

I've been using my mac for a few days without an external display and haven't noticed a crash. Once the external display was connected, the issue started again.

fdawans commented 3 weeks ago

I stopped using Alttab because it was not reliable, and then I just tried it again. But I also have a bug after sleep/lock where alttab does not pick up windows anymore (I need to restart it) My mac was also connected to an external display, so that might be the issue as well.

lwouis commented 3 weeks ago

@fdawans i believe you're probably facing the pinned issue #1324

CzBiX commented 3 weeks ago

Since this crash is related to checking the recording permissions, and I don't use the thumbnail feature. I modified the app to skip this checking code in: https://github.com/lwouis/alt-tab-macos/blob/97951e7e8e9a1ab480a53279cf0f08160de28301/src/logic/SystemPermissions.swift#L17

Voila, I have not encountered a crash since then.

@lwouis is it possible to skip the recording permissions checking when thumbnail feature isn't enabled?

lwouis commented 3 weeks ago

@CzBiX please see #1082 for more details on this