SFCertificateView Memory Leak

I've been spending days trying to solve the memory leak in a small menu bar application I've wrote (SC Menu). I've used Instruments which shows the leaks and memory graph which shows unreleased allocations. This occurs when someone views a certificate on the smartcard.

Basically it opens a new window and displays the certificate, the same way Keychain Access displays a certificate. Whenever I create an SFCertificateView instance and set setDetailsDisclosed(true) - a memory leak happens. Instruments highlights that line.

import Cocoa
import SecurityInterface

class ViewCertsViewController: NSViewController {
    var selectedCert: SecIdentity? = nil
    
    override func viewDidLoad() {
        super.viewDidLoad()

        self.view = NSView(frame: NSRect(x: 0, y: 0, width: 500, height: 500))
        self.view.wantsLayer = true
        
        var secRef: SecCertificate? = nil
        
        guard let selectedCert else { return }
        let certRefErr = SecIdentityCopyCertificate(selectedCert, &secRef)
        if certRefErr != errSecSuccess {
            os_log("Error getting certificate from identity: %{public}@", log: OSLog.default, type: .error, String(describing: certRefErr))
            return
        }
        let scrollView = NSScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.borderType = .lineBorder
        scrollView.hasHorizontalScroller = true
        scrollView.hasVerticalScroller = true

        let certView = SFCertificateView()
        guard let secRef = secRef else { return }
        
        certView.setCertificate(secRef)
        certView.setDetailsDisclosed(true)
        certView.setDisplayTrust(true)
        certView.setEditableTrust(true)
        certView.setDisplayDetails(true)
        certView.setPolicies(SecPolicyCreateBasicX509())
        certView.translatesAutoresizingMaskIntoConstraints = false

        scrollView.documentView = certView
        view.addSubview(scrollView)

        // Layout constraints
        NSLayoutConstraint.activate([
            scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            scrollView.topAnchor.constraint(equalTo: view.topAnchor),
            scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),

            // Provide certificate view a width and height constraint
            certView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
            certView.heightAnchor.constraint(greaterThanOrEqualToConstant: 500) 
        ])
    }

}
    

https://github.com/boberito/sc_menu/blob/dev_2.0/smartcard_menu/ViewCertsViewController.swift

Fairly simple.

Answered by DTS Engineer in 863312022

Thanks for bringing this to the forums.

As a first step I recommend that you extract this code into a small test project and see if the problem reproduces there. Ideally that project would not be tied to the presence of a smart card, but instead display a test certificate that’s embedded in the app.

If your test project reproduces the problem then none of the other code in your app is at fault, and that focuses the blame on SFCertificateView itself. In that case the next step is to file a bug against that API, making sure to include:

  • A sysdiagnose log taken shortly after reproducing the problem [1].
  • Your test project.

Please post your bug number, just for the record.

As to a workaround, I very much doubt there is one, but that’s unlikely to be a problem. Unless this leak is huge, it’s unlikely to affect the user in practice because there’s a limit to how fast they can show and hide your certificate viewer.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] It’s unlikely that this will be critical to diagnosing the issue, but it’s always good to include a sysdiagnose log because the log is used to triage and route your bug.

Accepted Answer

Thanks for bringing this to the forums.

As a first step I recommend that you extract this code into a small test project and see if the problem reproduces there. Ideally that project would not be tied to the presence of a smart card, but instead display a test certificate that’s embedded in the app.

If your test project reproduces the problem then none of the other code in your app is at fault, and that focuses the blame on SFCertificateView itself. In that case the next step is to file a bug against that API, making sure to include:

  • A sysdiagnose log taken shortly after reproducing the problem [1].
  • Your test project.

Please post your bug number, just for the record.

As to a workaround, I very much doubt there is one, but that’s unlikely to be a problem. Unless this leak is huge, it’s unlikely to affect the user in practice because there’s a limit to how fast they can show and hide your certificate viewer.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] It’s unlikely that this will be critical to diagnosing the issue, but it’s always good to include a sysdiagnose log because the log is used to triage and route your bug.

Hey thanks for the reply @DTS Engineer

FB20779944

As simple as a 2 line project basically created the leak in SFCertificateView. So everything should be there that's needed in the feedback.

SFCertificateView Memory Leak
 
 
Q