last night my code worked. today, it is randomly failing with multiple EXC_BAD_ACESS errors

last night my code worked. today, it is randomly failing with multiple EXC_BAD_ACESS errors


it was throwing an error when I added an element to an existing array like this:

self.view?.node?.children += [node]


I replaced that code with :

if let aNode = self.view?.node{
     aNode.children.append(node)
}


and for 1 test it worked fine. But i got another error with another array in a completely unrealted section of the app.


then the next time I ran, trying to fix the other error... The code i replaced started throwing errors.


the only difference was that I ran the OS update last night. 10.12.6. Ok so I'm working with beta 2 of Xcode 9... I checked and ther eis an update: beta 4.

updated to that, cleaned the code, rebuilt... same error.


My code, which was written in Swift 4, which worked yesterday, compiles and has apparently hundreds of EXC_BAD_ACCRESS errors now.

what gives? any ideas? I have checked in code that the array exists, and the the object I am adding to it exists. there's nothing in my code that is changing that in any way, when I try to append the object to the array. and like I said: this is tested and working code, that until last night had been humming along happily in thousands of tests.

so... I have a deInit function in my CNNode class. and I put an NSLog in it, that says:

NSLog("throwing away "+self.objName)


and I customized my doc object's name.

it never gets deinitialized. so, more confirmation that the debugger is not lying to me.

What is the backtrace (the first 10 or so lines at least) at the time of the crash? In the debugger window, you can type the "bt" command display it in text form, and then paste the beginning of it into a post.


Also, what thread is crashing? The main thread is thread 1. Is it crashing there, or in a background thread?


Based on your description of the symptoms, it sounds you you have an observation of some kind (KVO or NotificationCenter) either to or from an object that's getting released. Eventually, something is receiving the notification, and then you see a crash. That would be consistent with the crash appearing in different places in different runs of your app.


I strongly recommend you stop changing the source code. As long as you can re-create the crash with the current code, you should look for the problem in the code you've got. (Adding logging doesn't count as changing the source code, but in this type of problem it may move the crash around. That's why it's better to use the debugger, since you can keep re-running the same code without recompiling.)

#0 0x00007fff8c3780d2 in object_isClass () #1 0x00007fff78bf6648 in -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:usingBlock:] () #2 0x00007fff78a7b95d in -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] () #3 0x00007fff78ae423b in _NSSetObjectValueAndNotify () #4 0x000000010bfafe22 in CNMouseMan.performDragOperation(_:) at /Volumes/curie/bkTools/concrete_2017/concrete/CNTestPlugin/CNTestController.swift:355 #5 0x00000001003c0c3d in CNView.performDragOperation(_:) at /Volumes/curie/bkTools/concrete_2017/concrete/CNDisplayTech/CNView.swift:213 #6 0x00000001003c0ca8 in @objc CNView.performDragOperation(_:) () #7 0x00007fff74dffeb9 in NSCoreDragReceiveMessageProc () #8 0x00007fff75d3b8c2 in DoMultipartDropMessage () #9 0x00007fff75d3b5cc in DoDropMessage () #10 0x00007fff75d3b59d in SendDropMessage ()

no.

I know what a KVO observation object getting released looks like. You get a very descriptive error message. I've been fixing those for a while now.


this is something else. To me it looks like what you'd get if you relied on an Object that Apple was faking for performance in WebObjects. It's not really there, so you can't work with it, but they make it look like it's there. because sometimes it has to be there.


but like I said... the objects in question are not being released, and I am very carefully checking to be sure about that.


there is a relatively new object, that is a property of the CNNode object, for which I have Observation of one of it's variables. and if that object was set instead of it's property, That might do it. But I just checked that. there's no code at all that does that in the entire project, and with a handy didSet{} I saw that nothing makes that change.

QuinceyMorris,

I do not know a single person that can follow the backtrace. aside from the real text, the rest is gibberish. I have looked for, but never found a resource that can explain how to make use of it. Xcode has a great number of features that are opaque to users, and lack even the most basic instruction. Shark for instance... completely inaccessible.

making incremental changes and observing the behavior of the objects is the most efficient thing I can do. But hey, I'm self taught. And I've only ever run into a single issue that I could not solve. letting Xcode convert my Swift code from v2 to v3. it didn't compile, I didn't get any error message at all.

so i re-wrote it from scratch, leapfrogging 3, and moving to 4.

That's one reason to post the BT information. Other people may be able to help with it.


Reasoning about what your code does is good, but there are two problems in some cases:


1. If you're missing a piece of information, you may not be able to reason about the right thing.


2. If you're looking in the wrong place, your reasoning may be correct but unhelpful.


Backtraces help with #2, sometimes.

That's one reason to post the BT information. Other people may be able to help with it.

Right. Here’s the backtrace from earlier, reformatted to be a bit more readable:

#0 … object_isClass () 
#1 … -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:usingBlock:] () 
#2 … -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] () 
#3 … _NSSetObjectValueAndNotify () 
#4 … CNMouseMan.performDragOperation(_:) at …/CNTestController.swift:355 
#5 … CNView.performDragOperation(_:) at …/CNView.swift:213 
#6 … @objc CNView.performDragOperation(_:) () 
#7 … NSCoreDragReceiveMessageProc () 
#8 … DoMultipartDropMessage () 
#9 … DoDropMessage () 
#10… in SendDropMessage ()

@eblu, It looks like frame 4 is changing some property (on line 355 of

CNTestController.swift
) that’s crashing during KVO notification. I suggest you look at that line of code to determine what type of object and what property is in play.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi Eskimo,


ok, so I have results. I now know things that I did not know earlier.

if you release an object that you are observing, the system will give you a very detailed and elaborate error message in the output.


But... if you release the observer instead of the observed, you get no such error. the app just gets a memory error at the point in your app where that notification is sent out. There is no elaborate and helpful error message. Eskimo, what you noticed in the Back trace is literally the only thing I was certain of at the start of this process. (so I hope you can understand why I really did laugh when i got that advice.)


The BackTrace did confirm that it was a notification error (thank you QuiceyMorris, that was your pickup there.)


But we were already on the path to untangling that knot in the process I was already chewing on with Claude31.


I had a weekend of "Not thinking about this." And came back to it this monday morning, with a different approach. I will never be able to make sense out of BackTrace, without some kind of resource i can read, that explainsd what and why (and if you have one I am more than willing to get it and read it... I read the book on the old Pascal debugger MPC? for mac os 7 when I was a preteen, so its not like I'm not interested, the resources just don't seem to exist,) but my understanding of what i wrote, and what we've already confirmed should be enough to find the 8Ball. My error is based on the need to balance setting up and releasing observers. I have to have at least 1 unbalanced addObserver in my code. And I can know which objects are being released.


so I put breakpoints at every single addObserver/removeObserver in the classes that I suspected were hiding the 8Ball. and then for each addObserver, I added it to a checklist in a Numbers document for each individual object. Then I went through the steps to put the app in the failure mode, and checked off each remove observer call. It took a few tries because I learned that many of my addObserver/removeObserver calls are happening in ancestors of my class.


and here is the result: my classes, are part of a class hierarchy, and one of the objects in the middle of one of those hierarchies, did not pass through a call to a method that released observation in an object that I was releasing.


so the common ancestor releases an observation of a common property.

my class, releases the observation of specific properties, and it calls : super.unload() (which is the method I use to release observation)

and a class somewhere in the between those two classes, did not call: super.unload()

so the common property observations were never released.


of course, this was all very far away from where I was looking. (on line 355 of

CNTestController.swift
) and my focus at the start of this, was on that line.


thank you all for your help. especially Caulde31.

last night my code worked. today, it is randomly failing with multiple EXC_BAD_ACESS errors
 
 
Q