EXC_BAD_ACCESS (code=2, address=0x16d0f3ff0)

Hi!

I am developing an app (in XCode Version 11.2 and Swift 4.2) in which I fill in a LinkedList and after working with it, removing the elements that compose it produces the Thread 1 error: EXC_BAD_ACCESS (code = 2, address = 0x16d0f3ff0). The error occurs even without working with the items in the list, simply by adding them and trying to eliminate them the error already occurs. The tests I am doing with an iPhone with IOS version 11.4.1


The method that eliminates the elements of the LinkedList is removeAll.


The error occurs in the first line:


public func removeAll() {
self.head = nil //Thread 1: EXC_BAD_ACCESS (code=2, address=0x16d0f3ff0)
self.tail = nil
self.count = 0
} // removeAll


the definition of the variables 'head', 'tail', 'count':


  private var head: Node<T>?
private var tail: Node<T>?
public private(set) var count: Int = 0


And the type Node<T>:


public class Node<T> {
var value: T
var next: Node<T>?
weak var previous: Node<T>?
init(value: T) {
self.value = value
} // init
} // Node


With the debugger I see that the error occurs when assigning the value nil to self.head (in removeAll()). Just before self.head has correct values, it becomes nil and the error is skipped before reaching the next instruction.


In the Debug Navigator, in the stackTrace the last 2 functions where the error is seen:


libobjc.A.dylib`_object_remove_assocations:
0x180d11eec <+0>: sub sp, sp, #0x70 ; =0x70
-> 0x180d11ef0 <+4>: stp x26, x25, [sp, #0x20] //Thread 1 error: EXC_BAD_ACCESS (code = 2, address = 0x16d0f3ff0)
0x180d11ef4 <+8>: stp x24, x23, [sp, #0x30]
libswiftCore.dylib`_swift_release_:
0x104e18d1c <+180>: bl 0x104e1a37c ; bool swift::RefCounts<swift::SideTableRefCountBits>::doDecrement<(swift::PerformDeinit)1>(unsigned int)
-> 0x104e18d20 <+184>: ldp x29, x30, [sp], #0x10. //Thread 1 error: EXC_BAD_ACCESS (code = 2, address = 0x16d0f3ff0)
0x104e18d24 <+188>: ret



Does someone have idea how to resolve it?

Thanks!

Answered by OOPer in 392762022

Something like this, removing the last element in the linked list:

    public func removeTail() {
        guard let tail = tail else {return}
        if let prev = tail.previous {
            prev.next = nil
            self.tail = prev
        } else {
            self.head = nil
            self.tail = nil
        }
        count -= 1
    }

How long is the linked list when this error occures?


In my experience, too many linked objects may cause such an issue under ARC.

In this case, 4389 elements. How many elements approximately can produce this error?

That number is far less than I experienced, but depends on many things.


With a simplified project I created, 50000 is enough to reproduce the same issue.

Please try this:

    public func removeAll() {
        while head != nil {
            removeTail()
        }
    }

(If you do not have `removeTail()` yet, please define it.)

I do not understand. That will make it stay in an infinite loop, right? What should removeTail do?

Accepted Answer

Something like this, removing the last element in the linked list:

    public func removeTail() {
        guard let tail = tail else {return}
        if let prev = tail.previous {
            prev.next = nil
            self.tail = prev
        } else {
            self.head = nil
            self.tail = nil
        }
        count -= 1
    }

It works perfectly. I was totally blocked with this. Thank you very much!!

I investigated right today a similar issue happening in my code.

The error Thread 1: EXC_BAD_ACCESS (code=2, address=0x101744d41) was happening at line 8


    var emptyUsersListView: some View {
        List {
            EmptyView()
        }
        .navigationBarItems(trailing:
            Button(store.state.loginButtonText) {
                self.store.send(.tapOnLogin)
            }
        )
    }


After hours of digging, I narrowed it down to the Store class.

The crashed thread stack trace gave me the hint: the top frame is about the objectWillChangePublisher of Combine ObservableObject.


#0 0x0000000101744d41 in got.$s25ObjectWillChangePublisher7Combine010ObservableA0PTl ()
#1 0x0000000101571bcb in closure #2 in RootContainerView.emptyUsersListView.getter
#2 0x00007fff2c014579 in PrimitiveButtonStyleConfiguration.trigger() ()
#3 0x00007fff2c12bd20 in partial apply for PrimitiveButtonStyleConfiguration.trigger() ()
#4 0x00007fff2c35b67a in closure #1 in PressableGestureCallbacks.dispatch(phase:state:) ()
#5 0x00007fff2c1b7cec in thunk for @escaping @callee_guaranteed () -> () ()
#6 0x00007fff2c316d21 in partial apply for thunk for @escaping @callee_guaranteed () -> () ()
#7 0x00007fff2c317b79 in thunk for @escaping @callee_guaranteed () -> ()partial apply ()


So I had a closer look at the Store class, whose property sections look a bit like this.


    // MARK: - Public properties
    
    public var objectWillChange: AnyPublisher<_Reducer.State, Never> {
        return objectWillChangeSubject.eraseToAnyPublisher()
    }

    public private(set) var state: _Reducer.State {
        willSet { objectWillChangeSubject.send(newValue) }
    }

    // MARK: - Private properties

    private let objectWillChangeSubject = PassthroughSubject<_Reducer.State, Never>()


Do you see what your code and my code have in common? The following line:


   public private(set) var foo: Bar


So today, just without even knowing what I was doing, I changed the access modifiers of foo to


     public var foo: Bar


and that fixed the issue!!! I checked that also this version works.


     public internal(set) var foo: Bar


Now I would love to understand why this fixed the issue.

As much as I would like to know if such a fix would work in your case too.

Is public private(set) the real reason of the crash?


My Store class would be way more robust with the private modifier, but meanwhile, I can live with the less restricted modifier.

EXC_BAD_ACCESS (code=2, address=0x16d0f3ff0)
 
 
Q