提问者:小点点

在仪器中进行分析时出现SIGSEGV(坏内存访问)错误


我试图捕捉内存泄漏和保留周期与泄漏剖析工具在仪器工具。 然而,每当我点击仪器中的记录按钮时,app看起来像是启动然后崩溃。 如果我从Xcode打开应用程序并将其传输到Instruments,在我单击任何UIbutton后,应用程序崩溃。 如果我从模拟器打开应用程序,我可以得到第二个屏幕,但随后它也崩溃了。 此外,App在内存图中没有显示任何泄漏,在正常使用时也没有崩溃。

这是崩溃日志;

异常类型:EXC_BAD_ACCESS(SIGSEGV)异常子类型:KERN_INVALID_ADDRESS位于0x00000000000018 VM区域信息:0x18不在任何区域中。 以下区域之前的字节:4377985000区域类型开始-结束[VSIZE]PRT/MAX SHRMOD区域详细信息开始时未使用的空间-->
__text 0000000104F2C000-0000000104FBC000[576K]R-X/R-X SM=Co...TI应用程序测试]

终止信号:分段错误:11终止原因:命名空间信号,代码0xB终止进程:exc处理程序[0]由线程触发:0

筛选的syslog:找不到

线程0名称: 调度队列: com.apple.main-thread线程0崩溃: 0 libswiftcore.dylib 0x000000010597b2b4 0x1058cc000+717492 1 libswiftcore.dylib
0x000000010598823c 0x1058cc000+770620 2 uifoundation
0x000000018f01fbdc attributeDictionaryHash+460 3 Foundation
0x0000000185417edc hashProbe+72 4 Foundation
0x0000000185417e7c-[NSConcreteHashTable GetItem:] +40 5
UIFoundation 0x000000018f01fd54+[NSAttributeDictionary newWithDictionary:] +136 6基础0x000000018542666C-[NSConcreteAttributedString InitWithString:Attributes:] +124 7我的应用程序测试
0x0000000104FBB894 0x104F2C000+587924 8我的应用程序测试
0x0000000104FBA588 0x104F2C000+583048 9我的应用程序测试
0x0000000104FBA494 0x104F2C000+582804 10我的应用程序测试
0x0000000104FB9964 0x104F2C000+579940 11我的应用程序测试
0x0000000104FB9830 0x104F2C000+579632 12我的应用程序测试
0x0000000104FBC608 0x104F2C000 0x0000000104F85470 0x104F2C000+365680 20我的应用程序测试0x0000000104F85688 0x104F2C000+366216 21 UIKit 0x000000018DF6B20C-[UIApplication SendAction:To:From:Forevent:]+96 22 UIKit 0x000000018DF6B18C-[UIControl SendAction:To:Forevent:]+80 23 UIKit 0x000000018DF55F4C-[UIControl_SendActions Forevents:WithEvent:]+440 24 UIKit 0x000000018DF6AA80-[UIControl opDoSources0+204 34 CoreFoundation 0x0000000184ACD738__CFRunloopRun+1048 35 CoreFoundation
0x00000001849EE2D8 CFRunloopRun Specific+436 36 GraphicsServices
0x000000018687FF84 GSEventRunModal+100 37 UIKIT
0x000000018DF9A880 UIApplicationMain+208 38我的应用程序测试
0x0000000104F97854 0x104F2C000+440404 39 libdyld.dylib
0x000000018451256C start+4

线程1:0 libsystem_kernel.dylib 0x0000000184641dbc__workq_kernreturn+8 1 libsystem_pthread.dylib 0x0000000184753144_pthread_wqthread+1288 2
libsystem_pthread.dylib 0x0000000184752c30 start_wqthread+4

线程2:0 libsystem_pthread.dylib 0x0000000184752c2c start_wqthread+0

线程3名称:com.apple.UIKit.eventfetch-线程线程3:0
libsystem_kernel.dylib 0x0000000184620bc4 mach_msg_trap+8 1 libsystem_kernel.dylib 0x0000000184620a3c mach_msg+72 2
CoreFoundation 0x0000000184acfce4 CFRunLoopServiceMachPort+196 3 CoreFoundation 0x0000000184acd8b0__cfrunlooprun+1424 4 CoreFoundation
0x00000001849ee2d8

线程4:0 libsystem_pthread.dylib 0x0000000184752c2c start_wqthread+0

线程5名称:com.apple.nsurlConnectionLoader线程5:0
libsystem_kernel.dylib 0x0000000184620bc4 mach_msg_trap+8 1 libsystem_kernel.dylib 0x0000000184620a3c mach_msg+72 2
CoreFoundation 0x0000000184acfce4 CFRunLoopServiceMachPort+196 3 CoreFoundation 0x0000000184acd8b0__cfrunlooprun+1424 4 CoreFoundation
0x00000001849ee2d8

线程0崩溃,ARM线程状态(64位):X0:0x00000001C4227AC0 X1:0x000000018ECA2DB2 X2:0x000000016AECF908 X3:0x000000000000000000000020X5:0x0000000000000020X6:0x000000000185426654 X7:0x0000000000000000000000X9:0x00000000000000X10:0x011949010119480X11:0x000000000119480X12:0x000000000001194800X

我搜索了一个月,我不确定这是不是一个仪器错误。 我查看了下面的帖子;

Xcode Instruments:泄漏-应用程序在启动时崩溃

使用漏电仪器时仪器撞毁

导致应用程序崩溃的xcode仪器

编辑:另一个崩溃日志。 在这个例子中,我打开应用程序并将内存转移到Instruments工具,然后触摸UIView顶部,打开一个新的控制器。

日期/时间:2018-07-06 15:13:34.5980+0300发布时间:2018-07-06 15:13:19.6298+0300操作系统版本:iPhone OS 11.0(15A372)基带版本:2.00.01报告版本:104

异常类型:EXC_BAD_ACCESS(SIGSEGV)异常子类型:KERN_INVALID_ADDRESS位于0x00000000000018 VM区域信息:0x18不在任何区域中。 以下区域之前的字节:4330094568区域类型起始-结束[VSIZE]PRT/MAX SHRMOD区域详细信息起始处未使用的空间-->
__text 0000000102180000-00000001022A0000[1152k]R-X/R-X SM=COW.。。TI Filo Test]

终止信号:分段错误:11终止原因:命名空间信号,代码0xB终止进程:exc处理程序[0]由线程触发:0

筛选的syslog:找不到

线程0名称:分派队列:com.apple.main-线程线程0崩溃:0 libswiftcore.dylib 0x0000000102bdf278 0x102b30000+717432 1 libswiftcore.dylib
0x0000000102bec1b0 0x102b30000+770480 2 corefoundation
0x0000000184a3ec80-[NSDictionary Allkey]+108 3 UIKit
0x000000018e15738c-[NSDictionary+2294668(UIStringDrawingKeyCompatibility) 2 UIKit 0x000000018E5B23FC_UigestureEnvironmentUpdate+1056 13 UIKit
0x000000018E5B1F88-[UigestureEnvironment_DeliverEvent:ToGestureRecognizers:UsingBlock:]+404 14 UIKit 0x000000018E5B10E4-[UigestureEnvironment_UpdateGestureForEvent:Window:]+276 15 UIKit 0x000000018DF65A54-[UIWindow Sendevent:]+3180 16 UIKit l+100 26 UIKIT
0x000000018DF9A880 UIApplicationMain+208 27我的应用程序测试
0x00000001021FACDC 0x102180000+503004 28 libdyld.dylib
0x000000018451256C启动+4

线程1:0 libsystem_pthread.dylib 0x0000000184752c2c start_wqthread+0

线程2:0 libsystem_pthread.dylib 0x0000000184752c2c start_wqthread+0

线程3:0 libsystem_pthread.dylib 0x0000000184752c2c start_wqthread+0

线程4名称:com.apple.UIKit.eventfetch-线程线程4:0
libsystem_kernel.dylib 0x0000000184620bc4 mach_msg_trap+8 1 libsystem_kernel.dylib 0x0000000184620a3c mach_msg+72 2
CoreFoundation 0x0000000184acfce4 CFRunLoopServiceMachPort+196 3 CoreFoundation 0x0000000184acd8b0__cfrunlooprun+1424 4 CoreFoundation
0x00000001849ee2d8

线程5名称:GAIThread线程5:0 libsystem_kernel.dylib
0x0000000184620bc4 mach_msg_trap+8 1 libsystem_kernel.dylib
0x0000000184620a3c mach_msg+72 2 CoreFoundation
0x0000000184acfce4 CFRunLoopServiceMachPort+196 3
CoreFoundation 0x0000000184acd8b0__cfrunlooprun+1424 4 CoreFoundation 0x00000001849ee2d8 CFRunLoopRunSpecific+436

线程6名称:com.apple.nsurlConnectionLoader线程6:0
libsystem_kernel.dylib 0x0000000184620bc4 mach_msg_trap+8 1 libsystem_kernel.dylib 0x0000000184620a3c mach_msg+72 2
CoreFoundation 0x0000000184acfce4 CFRunLoopServiceMachPort+196 3 CoreFoundation 0x0000000184acd8b0__cfrunlooprun+1424 4 CoreFoundation
0x00000001849ee2d8

线程0由于ARM线程状态(64位)而崩溃:x0:0x00000001C4227C60 x1:0x000000018ECA2DB2 x2:0x00000000000000000000000000X3:0x00000000010637E8D0 x4:0x0000000000000020X5:0x0000000000000020X6:0x0000000001021E82E8 x7:0x00000000000000B70 x8:0x0000000000000000X9:0x0000000000000000X10:0x01446B0101446B80X11:0x000000000001446B01

编辑:在@franticrock s的回答之后。 当我删除[UINavigationBarsetTitleTextAttributes:]时,detail类可以打开,但没有显示任何项(标题,后退按钮或任何单元格)。 它们都是空的,我还在漏水。

这里是controller类,我在这里编写[UINavigationBar SetTitleTextAttributes:]

class WelcomeViewController: BaseViewController {

let bgView = UIView()
let backgroundImage = UIImageView()

let logoImage: UIImageView = {
    let i = UIImageView()
    i.image = UIImage(named: "full_logo")
    i.contentMode = .scaleAspectFit
    return i
}()

let welcomeLabel : UILabel = {
    let l = UILabel()
    l.font = Fonts.font.withSize(24)
    l.textColor = UIColor.white
    l.textAlignment = .center
    l.numberOfLines = 0
    l.sizeToFit()
    return l
}()

let loginLbl: UILabel = {
    let l = UILabel()
    l.font = Fonts.font.withSize(13)
    l.textColor = UIColor.white
    l.textAlignment = .center
    l.numberOfLines = 0
    l.sizeToFit()
    return l
}()

let adminBtn: UIButton = {
    let b = UIButton()
    b.backgroundColor = Color.Common.buttonColor
    b.layer.cornerRadius = 6.0
    return b
}()

let userBtn: UIButton = {
    let b = UIButton()
    b.backgroundColor = Color.Common.buttonColor
    b.layer.cornerRadius = 6.0
    return b
}()

lazy var supportedServicesView = WelcomeScreenButtonView(text: getLabelText(key: CMSKeys.CMS_LBL_SUPPORTEDSERVICES), imageName: "phone")
lazy var incidentView = WelcomeScreenButtonView(text: getLabelText(key: CMSKeys.CMS_LBL_INCIDENT), imageName: "phone")
lazy var contactUsView = WelcomeScreenButtonView(text: getLabelText(key:CMSKeys.CMS_LBL_CONTACT), imageName: "phone")
lazy var moreView = WelcomeScreenButtonView(text: getLabelText(key:CMSKeys.CMS_LBL_MORE), imageName: "wdiger")

lazy var emergencyBtn = SendButton(text: "Button")

let firstStackView = UIStackView()
let secondStackView = UIStackView()
let thirdStackView = UIStackView()

let btnStackView = UIStackView()

override func viewDidLoad() {
    super.viewDidLoad()
    self.setPageID()
    designUI()
}

override func viewDidAppear(_ animated: Bool) {
    if(AppContext.instance.comesFromURL != nil){
        comesFromURL()
    }
}
override func viewWillAppear(_ animated: Bool) {
    if(analyticsName != nil){
        self.sendDataToGA()
    }
}

override func viewDidLayoutSubviews() {

    bgView.anchor(self.thirdStackView.topAnchor, left: self.view.leftAnchor, bottom: self.view.bottomAnchor, right: self.view.rightAnchor, topConstant: 40, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0)

    let margins = view.layoutMarginsGuide
    thirdStackView.leadingAnchor.constraint(equalTo: margins.leadingAnchor,constant: 5).isActive = true
    thirdStackView.trailingAnchor.constraint(equalTo: margins.trailingAnchor,constant: -5).isActive = true
    thirdStackView.bottomAnchor.constraint(equalTo: self.emergencyBtn.topAnchor, constant: -10).isActive = true
    thirdStackView.heightAnchor.constraint(equalTo: thirdStackView.widthAnchor, multiplier: 0.77).isActive = true

    emergencyBtn.anchor(nil, left: self.view.leftAnchor, bottom: self.bottomLayoutGuide.topAnchor, right: self.view.rightAnchor, topConstant: 10, leftConstant: 20, bottomConstant: 20, rightConstant: 20, widthConstant: 0, heightConstant: 48)
    if #available(iOS 11.0, *) {
        logoImage.anchor(self.view.safeAreaLayoutGuide.topAnchor, left: self.view.leftAnchor, bottom: nil, right: self.view.rightAnchor, topConstant: 40, leftConstant: 80, bottomConstant: 0, rightConstant: 80, widthConstant: 0, heightConstant: 0)
    } else {
        logoImage.anchor(self.view.topAnchor, left: self.view.leftAnchor, bottom: nil, right: self.view.rightAnchor, topConstant: 40, leftConstant: 80, bottomConstant: 0, rightConstant: 80, widthConstant: 0, heightConstant: 0)
        // Fallback on earlier versions
    }
    logoImage.anchorCenterXToSuperview()
    let welcomeLblHeight = heightForView(text: "Welcome", font: welcomeLabel.font, width: self.view.bounds.width)
    let loginLblHeight = heightForView(text: "Please Log In", font: loginLbl.font, width: self.view.bounds.width)
    welcomeLabel.anchor(self.logoImage.bottomAnchor, left: self.view.leftAnchor, bottom: nil, right: self.view.rightAnchor, topConstant: 0, leftConstant: 50, bottomConstant: 0, rightConstant: 50, widthConstant: 0, heightConstant: welcomeLblHeight)
    loginLbl.anchor(self.welcomeLabel.bottomAnchor, left: self.view.leftAnchor, bottom: nil, right: self.view.rightAnchor, topConstant: 10, leftConstant: 50, bottomConstant: 0, rightConstant: 50, widthConstant: 0, heightConstant: loginLblHeight)
    btnStackView.anchor(nil, left: self.view.leftAnchor, bottom: self.thirdStackView.topAnchor, right: self.view.rightAnchor, topConstant: 0, leftConstant: 20, bottomConstant: 20, rightConstant: 20, widthConstant: 0, heightConstant: 50)

    backgroundImage.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height - self.bgView.frame.height)
}

private func designUI(){
    self.view.translatesAutoresizingMaskIntoConstraints = true
    backgroundImage.image = UIImage(named: "background.png")
    backgroundImage.contentMode = .scaleAspectFill
    self.view.insertSubview(backgroundImage, at: 0)

    bgView.backgroundColor = Color.Common.welcomeScreenBackgroundColor
    self.view.insertSubview(bgView, at: 1)
    view.addSubview(logoImage)
    welcomeLabel.text = getLabelText(key: CMSKeys.CMS_LBL_WELCOME)
    view.addSubview(welcomeLabel)
    loginLbl.text = getLabelText(key: CMSKeys.CMS_LBL_LOGIN)
    view.addSubview(loginLbl)

    adminBtn.backgroundColor = Color.Common.adminGreen
    adminBtn.setTitle(getLabelText(key: CMSKeys.CMS_BTN_ADMIN), for: .normal)
    adminBtn.addTarget(self, action: #selector(adminBtnTapped(_:)), for: .touchUpInside)

    userBtn.backgroundColor = Color.Common.userGreen
    userBtn.setTitle(getLabelText(key: CMSKeys.CMS_BTN_USER), for: .normal)
    userBtn.addTarget(self, action: #selector(userBtnTapped(_:)), for: .touchUpInside)

    btnStackView.axis  = UILayoutConstraintAxis.horizontal
    btnStackView.distribution = UIStackViewDistribution.fillEqually
    btnStackView.alignment = UIStackViewAlignment.fill
    btnStackView.spacing = 10.0
    btnStackView.addArrangedSubview(adminBtn)
    btnStackView.addArrangedSubview(userBtn)
    btnStackView.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(btnStackView)

    firstStackView.axis  = UILayoutConstraintAxis.vertical
    firstStackView.distribution = UIStackViewDistribution.fillEqually
    firstStackView.alignment = UIStackViewAlignment.fill
    firstStackView.spacing = 10.0
    firstStackView.addArrangedSubview(supportedServicesView)
    firstStackView.addArrangedSubview(contactUsView)
    firstStackView.translatesAutoresizingMaskIntoConstraints = false

    secondStackView.axis  = UILayoutConstraintAxis.vertical
    secondStackView.distribution = UIStackViewDistribution.fillEqually
    secondStackView.alignment = UIStackViewAlignment.fill
    secondStackView.spacing = 10.0
    secondStackView.addArrangedSubview(incidentView)
    secondStackView.addArrangedSubview(moreView)
    secondStackView.translatesAutoresizingMaskIntoConstraints = false

    thirdStackView.axis = UILayoutConstraintAxis.horizontal
    thirdStackView.distribution = UIStackViewDistribution.fillEqually
    thirdStackView.alignment = UIStackViewAlignment.fill
    thirdStackView.spacing = 10.0
    thirdStackView.addArrangedSubview(firstStackView)
    thirdStackView.addArrangedSubview(secondStackView)
    thirdStackView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(thirdStackView)

    //View Tap Gestures
    let tapSupportedServices = UITapGestureRecognizer(target: self, action: #selector(self.tapSupportedServices(_:)))
    supportedServicesView.addGestureRecognizer(tapSupportedServices)
    supportedServicesView.isUserInteractionEnabled = true

    let tapIncidentView = UITapGestureRecognizer(target: self, action: #selector(self.tapIncident(_:)))
    incidentView.addGestureRecognizer(tapIncidentView)
    incidentView.isUserInteractionEnabled = true

    let tapContactUs = UITapGestureRecognizer(target: self, action: #selector(self.tapContactUs(_:)))
    contactUsView.addGestureRecognizer(tapContactUs)
    contactUsView.isUserInteractionEnabled = true

    let tapMoreView = UITapGestureRecognizer(target: self, action: #selector(self.tapMore(_:)))
    moreView.addGestureRecognizer(tapMoreView)
    moreView.isUserInteractionEnabled = true

    emergencyBtn.layer.cornerRadius = 6.0
    emergencyBtn.addTarget(self, action: #selector(emergenyBtnTapped(_:)), for: .touchUpInside)
    self.view.addSubview(emergencyBtn)

}

@objc func tapSupportedServices(_ sender: UITapGestureRecognizer) {
    let linkingVC = SupportedServicesFirstViewController()
    let controller = createNavController(title: "Services", viewController: linkingVC)
    self.present(controller, animated: true)
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

private func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{
    let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
    label.numberOfLines = 0
    label.lineBreakMode = NSLineBreakMode.byWordWrapping
    label.font = font
    label.text = text
    label.sizeToFit()

    return label.frame.height
}

//Gets a Title and a ViewController then returns a UINavigationController with attributes
private func createNavController(title: String, viewController: UIViewController) -> UINavigationController {
    viewController.view.backgroundColor = UIColor(red:0.87, green:0.87, blue:0.87, alpha:1.0)
    let navController = UINavigationController(rootViewController: viewController)
    navController.navigationBar.topItem?.title = title
    navController.navigationBar.barTintColor = Color.NavigationBar.tintColor
    navController.navigationBar.tintColor = UIColor.white
    //Fix: Leak
    navController.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: Color.NavigationBar.textColor]

    return navController
}

private func removeViews(){
    self.emergencyBtn.removeFromSuperview()
    self.incidentView.removeFromSuperview()
    self.moreView.removeFromSuperview()
    self.supportedServicesView.removeFromSuperview()
    self.contactUsView.removeFromSuperview()
}
deinit {
    print("Welcome Deinited")
    removeViews()
}
}

共2个答案

匿名用户

在第一个堆栈跟踪中,有与以下内容相关的代码:[UINavigationBar SetTitleTextAttributes:]
它试图通过设置标题上的文本属性来自定义导航栏。 你在这么做吗? 你能试着评论一下这个问题吗,看看问题会不会消失?

从技术上讲,你所得到的并不是内存泄漏。 您正在访问释放的对象。 您可以做的另一件事是在您正在运行的方案上启用僵尸对象,并查看是否可以获得关于哪个对象被释放的信息。

现在,如果上面的堆栈跟踪没有引导您找到任何您直接编写的代码,并且您说您已经使用了内存调试图工具,并且没有找到任何对正在检查泄漏的任何对象的强引用,那么我将在这里使用一种更有创造性的方法来查找问题。 我常用的方法是消除。 开始注释掉控制器的大部分,直到只剩下空壳。 每次,您都可以将代码削减一半(记录性能),并重新测试代码的哪一部分引用了释放的对象。

显然,由于正常的应用程序操作不会导致错误的访问异常,所以它可能与XCode/Instruments内部机制有关,但是上面的setTitleTextAttributes看起来很可疑,我将首先尝试缩小问题是否与导航栏有关的范围。 您是否对导航栏UI的导航层次结构或自定义做了什么奇怪的事情?

还要检查以前的导航事件/实例中的内存中是否存在同一视图控制器的其他实例。。。 这听起来像是一个UI对象正在被释放,然后由一个异步进程稍后更新。

同时覆盖您的deinit{}。 方法并在其中放入一个print语句,以检测正在释放的所有相关对象。 这将有助于缩小,哪个控制器正在释放和访问稍后。

它是发生在所有iOS版本/设备型号上,还是只发生在特定的版本/设备型号上?

匿名用户

这个问题提出了两个问题。 第一个问题是为什么分析会中断,第二个问题是为什么您的应用程序会出现释放后使用的问题。

@FranicRock对第二个问题提出了很大的建议。

对于分析问题,我的建议是尝试一种变通方法。 如果您的应用程序可以用Beta XCode10.0编译,那么您可以进入Edit Schema(命令-<),并在Diagnostics选项卡中为您的运行操作单击Logging Malloc Stack with子选项All Allocation and Free history。 然后您可以:

  1. 在模拟器中运行应用程序。
  2. 按调试器区域中的memory graph按钮(第8个图标,看起来像三个圆圈连接在一起)
  3. 执行文件->导出内存图。

你既可以自己研究记忆图,也可以把它放在像Pastebin这样的公共位置,让其他人提供见解。 苹果公司有一个关于这种新方法的信息丰富的视频:WWDC-2018-416-Memory-Deep-Dive