touchlab / xcode-kotlin

Kotlin Native Xcode Plugin
https://touchlab.co/xcodekotlin
Apache License 2.0
1.15k stars 47 forks source link

Xcode 15 beta crashes on launch if Xcode-kotlin is installed #96

Closed dvshelley closed 10 months ago

dvshelley commented 1 year ago

Install Xcode 15.0 I used build (15A5195l) - beta 4 Launch Xcode-beta Xcode immediately crashes run xcode-kotlin uninstall and Xcode-beta runs as expected.

I am running on an M series MBP with macOS 13.4.1 (c).

kpgalligan commented 1 year ago

It's an issue for sure (https://github.com/touchlab/xcode-kotlin/issues/95). We're hooking into Xcode through undocumented means, so the plugin breaking isn't entirely unanticipated, depending on how Xcode changes. We're looking into this one soon.

TadeasKriz commented 11 months ago

I've been looking into it and so far it seems to be a bug in Xcode itself. It happens with other 3rd party plugins as well. I also tried to extract Apple's plugin out of the Xcode.app bundle and it's crashing too.

I've filed a radar/feedback to Apple about this issue. Please go ahead and dupe it: https://openradar.appspot.com/radar?id=5500625966071808

Thanks!

johnqh commented 11 months ago

Still crashes after Xcode public release

Sniper-yj commented 11 months ago

Ladies and gentlemen, I have found a solution to this problem. It is preliminarily judged to be a bug in Xcode. The main cause of the problem is that an exception occurs in the cache directory of Xcode. The path is similar to "/private/var/folders//64/dz_kmw9x0qbd96ffx05gmdkr0000gp/C/com.apple.DeveloperTools/15.0-15A240d/Xcode/PlugInCache-Debug.xcplugincache". This file is missing the information of the "/Applications/Xcode.app/Contents/PlugIns/IDEPerformanceDebugger.framework" file in its plugin information, causing Xcode to have an exception when loading the plugin. If the IDEPerformanceDebugger information in PlugInCache-Debug.xcplugincache is supplemented, Xcode can be started normally and the plugin can be used. This was discovered while reverse engineering Xcode. The specific solution may require further research, I'm just providing an idea.

kpgalligan commented 11 months ago

Interesting, thanks for the info.

TadeasKriz commented 11 months ago

@Sniper-yj Thanks, that's a really good find! I'm gonna try and continue where you left off and see if there's a way to make it work transparently.

TadeasKriz commented 11 months ago

@Sniper-yj Added the IDEPerformanceDebugger.framework entry, but still getting the same crash. The entry:

<dict>
    <key>bundlePath</key>
    <string>/Applications/Xcode-15.0.0.app/Contents/PlugIns/IDEPerformanceDebugger.framework</string>
    <key>modificationDates</key>
    <array>
        <date>2023-10-13T17:05:54Z</date>
        <date>2023-10-13T17:05:54Z</date>
        <date>2023-10-13T17:05:50Z</date>
        <date>2023-10-13T17:05:50Z</date>
    </array>
    <key>path</key>
    <string>/Applications/Xcode-15.0.0.app/Contents/PlugIns/IDEPerformanceDebugger.framework</string>
    <key>plugInPlist</key>
    <dict>
        <key>plug-in</key>
        <dict>
            <key>extension-points</key>
            <dict/>
            <key>extensions</key>
            <dict>
                <key>Xcode.DebuggerFoundation.DebuggingAddition.RuntimePerformanceIssue</key>
                <dict>
                    <key>additionClass</key>
                    <string>IDEPerformanceDebugger.RuntimePerformanceIssueDebuggerAddition</string>
                    <key>id</key>
                    <string>Xcode.DebuggerFoundation.DebuggingAddition.RuntimePerformanceIssue</string>
                    <key>name</key>
                    <string>Performance Debugging Addition</string>
                    <key>point</key>
                    <string>Xcode.DebuggerFoundation.DebuggingAddition</string>
                </dict>
            </dict>
            <key>moduleName</key>
            <string>IDEPerformanceDebugger</string>
            <key>rules</key>
            <array>
                <dict>
                    <key>id</key>
                    <string>com.apple.dt.dbg.DebuggerFoundation</string>
                    <key>kind</key>
                    <string>plug-in</string>
                </dict>
                <dict>
                    <key>id</key>
                    <string>IDEPerformanceDebuggerEnabled</string>
                    <key>kind</key>
                    <string>user-default</string>
                </dict>
            </array>
            <key>validateClassValues</key>
            <true/>
        </dict>
        <key>version</key>
        <dict>
            <key>compiler-build</key>
            <real>22235</real>
            <key>file-format</key>
            <integer>1</integer>
        </dict>
    </dict>
</dict>

Did you have to do something else too? It's weird that this would be the reason for the crash, since it's crashing on registering the extension declared in the Kotlin.ideplugin.

EDIT: I haven't changed anything, but now the Xcode started up. That's seriously weird.

EDIT2: Oh, because it was the second startup that worked, I got it reproducible consistently now.

TadeasKriz commented 11 months ago

So it seems I found a way to get around the issue quite reproducibly. Doing the following steps workarounds the issue:

  1. defaults write com.apple.dt.xcode IDEPerformanceDebuggerEnabled -bool true && killall -u $USER cfprefsd
  2. Run Xcode - it will crash, but that's expected
  3. defaults delete com.apple.dt.xcode IDEPerformanceDebuggerEnabled && killall -u $USER cfprefsd

Afterwards the Xcode works as expected. We'll discuss adding it to the xcode-kotlin with @kpgalligan.

Sniper-yj commented 10 months ago

@TadeasKriz There is no problem with your addition. The issue lies in the modification dates within your IDEPerformanceDebugger. The time of item1 and item2 is equal to the modification time of the IDEPerformanceDebugger.framework, the time of item3 is the modification time of the IDEPerformanceDebugger.xcplugindata, and the time of item4 is the modification time of the IDEPerformanceDebugger soft link (very important). After adding these, there should be no problem. However, I see that your modification solution is to directly disable the IDEPerformanceDebugger feature, which I think is also fine, but I'm concerned that it may block some of the capabilities provided by Xcode for us.

qhhonx commented 10 months ago

So it seems I found a way to get around the issue quite reproducibly. Doing the following steps workarounds the issue:

  1. defaults write com.apple.dt.xcode IDEPerformanceDebuggerEnabled -bool true && killall -u $USER cfprefsd
  2. Run Xcode - it will crash, but that's expected
  3. defaults delete com.apple.dt.xcode IDEPerformanceDebuggerEnabled && killall -u $USER cfprefsd

Afterwards the Xcode works as expected. We'll discuss adding it to the xcode-kotlin with @kpgalligan.

Good investigation. Follow these instructions (with little modifications), Xcode still works with plugin installed.

As @Sniper-yj did awesome Reverse Engineering work found that Xcode 15 crashes when loading non apple plugins because its runtime scaned plugin records differ from the PlugInCache-Debug.xcplugincache file holded.

Here, I try to explain the above solution and give some suggestions.

In the last, I'm curioused about how you figured out the IDEPerformanceDebuggerEnabled key and where to found the IDEPerformanceDebugger.framework entry?

TadeasKriz commented 10 months ago

@qhhonx No need to uninstall the xcode-kotlin plugin, because the crash happens after Xcode writes the information about IDEPerformanceDebugger.framework into the plugin cache. The main thing that's needed is enabling the IDEPerformanceDebugger using the IDEPerformanceDebuggerEnabled property.

I found that property when debugging the Xcode itself and reverse engineering it. I found that the IDEPerformanceDebugger.framework wasn't being loaded by Xcode, because the property has no value and therefore it defaulted to false.

TadeasKriz commented 10 months ago

@TadeasKriz There is no problem with your addition. The issue lies in the modification dates within your IDEPerformanceDebugger. The time of item1 and item2 is equal to the modification time of the IDEPerformanceDebugger.framework, the time of item3 is the modification time of the IDEPerformanceDebugger.xcplugindata, and the time of item4 is the modification time of the IDEPerformanceDebugger soft link (very important). After adding these, there should be no problem. However, I see that your modification solution is to directly disable the IDEPerformanceDebugger feature, which I think is also fine, but I'm concerned that it may block some of the capabilities provided by Xcode for us.

The modification dates weren't the issue. As I mentioned in the edits, I just had to open Xcode the second time and it worked. That's because the first time the plugin cache wasn't updated in time, so it crashed the same way. The second run was fine.

Also, my modification is not disabling IDEPerformanceDebugger. That's disabled by default, and it's the reason why it's not in the plugin cache file. Instead, my workaround enables the IDEPerformanceDebugger.framework so that Xcode puts it in the cache and starts working.

TadeasKriz commented 10 months ago

@qhhonx Interestingly enough, this morning when I tried again, I had to uninstall the xcode-kotlin first, then do the three steps and then install it again. Otherwise it didn't work. Really weird that it did work for me before.

qhhonx commented 10 months ago

@qhhonx Interestingly enough, this morning when I tried again, I had to uninstall the xcode-kotlin first, then do the three steps and then install it again. Otherwise it didn't work. Really weird that it did work for me before.

It is expected for me. In our reverse engineering, we found that Xcode saves the plugin cache file in asynchronousel way so that the one who has installed one non apple plugin will crash and the plugin cache file maybe generated/updated or not. SO, one should uninstall the non apple plugins before do above fix instructions such that Xcode will run normally and generated/updated the plugin cache file in clean environment. After that, install any non apple plugins will not lead Xcode crash again.

TadeasKriz commented 10 months ago

We've released a new version of Xcode Kotlin CLI 1.3.0! Please go ahead and try it out, it contains the workaround for this crash.

jadar commented 10 months ago

I received an update on my Feedback Assistant report.

Thank you for filing the feedback report. Please verify this issue with Xcode 15.1 beta 2 and update your bug report with your results by logging into https://feedbackassistant.apple.com/ or by using the Feedback Assistant app.

Xcode 15.1 beta 2 (15C5042i) https://developer.apple.com/download/ Posted Date: October 26, 2023

I downloaded the new Xcode beta, cleared my caches, and it opened just fine. I then cleared the cache for the old version and tried it again—and it crashed. So I believe Apple has resolved this issue even without the workaround.

kpgalligan commented 10 months ago

Hmm, interesting. Thanks for the update!

TadeasKriz commented 10 months ago

Thanks for the update! I'll change the CLI to only apply the workaround for Xcode 15.0 then.