Originally created by @sidmani on GitHub (Sep 10, 2017).
In ObjectObserver.swift (line 325) and ListMonitor.swift (line 714), ObjectType.cs_fromRaw(object: rawObject) causes a segfault, but only when profiling, not regular building. The strange thing is I can't replicate the issue in the demo project. Do you have any idea what causes this? Commenting out the callback invocation fixes the problem.
Originally created by @sidmani on GitHub (Sep 10, 2017).
In ObjectObserver.swift (line 325) and ListMonitor.swift (line 714), ` ObjectType.cs_fromRaw(object: rawObject)` causes a segfault, but only when profiling, not regular building. The strange thing is I can't replicate the issue in the demo project. Do you have any idea what causes this? Commenting out the callback invocation fixes the problem.
adam
added the fixed label 2025-12-29 15:26:00 +01:00
@JohnEstropia I made a mistake, the [weak self] is to blame. Both that and [unowned self] cause a segfault. I still don't know why though.
@sidmani commented on GitHub (Sep 12, 2017):
@JohnEstropia I made a mistake, the `[weak self]` is to blame. Both that and `[unowned self]` cause a segfault. I still don't know why though.
@sidmani Are those [weak self] and [unowned self] within CoreStore's source file? If it's in external code, can you show an example pattern this occurs?
@JohnEstropia commented on GitHub (Sep 12, 2017):
@sidmani Are those [weak self] and [unowned self] within CoreStore's source file? If it's in external code, can you show an example pattern this occurs?
Yeah, they're in CoreStore's source (line 317 in ObjectMonitor.swift, for example). I'm debugging this right now, and by replacing the callback at line 325 with a function call to a temporary function:
I get the compiler error: Cannot convert value of type 'ObjectMonitor<D>' to expected argument type 'ObjectMonitor<_>'. In theory there should be no difference between calling a closure and a function with the same input and return types, so I think this is the issue. Not sure how to fix yet.
@sidmani commented on GitHub (Sep 12, 2017):
Yeah, they're in CoreStore's source (line 317 in ObjectMonitor.swift, for example). I'm debugging this right now, and by replacing the callback at line 325 with a function call to a temporary function:
```
func debugSegfault(_ monitor: ObjectMonitor<ObjectType>, object: ObjectType) {
}
private func registerObjectNotification(_ notificationKey: UnsafeRawPointer, name: Notification.Name, toObserver observer: AnyObject, callback: @escaping (_ monitor: ObjectMonitor<ObjectType>, _ object: ObjectType) -> Void) {
cs_setAssociatedRetainedObject(
NotificationObserver(
notificationName: name,
object: self,
closure: { [weak self] (note) in
guard let `self` = self,
let userInfo = note.userInfo,
let object = userInfo[String(describing: NSManagedObject.self)] as! NSManagedObject? else {
return
}
self.debugSegfault(self, object: object)
// callback(strongSelf, ObjectType.cs_fromRaw(object: object))
}
),
forKey: notificationKey,
inObject: observer
)
}
```
I get the compiler error: `Cannot convert value of type 'ObjectMonitor<D>' to expected argument type 'ObjectMonitor<_>'`. In theory there should be no difference between calling a closure and a function with the same input and return types, so I think this is the issue. Not sure how to fix yet.
it seems that ObjectType.cs_fromRaw (object: object) was doing weird casting and the compiler does not like when is archiving or profiling, so I think we can check if the object implements the ObjectType in the guard.
after the correction my app is archiving successfully @sidmani, just I want to know @JohnEstropia if this is a valid fix and doesn't affect to something else, it seems that my app runs perfect but I'm not using ListObserver or MonitorObserver, so just let me know any comment
@SoyArpad commented on GitHub (Sep 21, 2017):
it seems that ObjectType.cs_fromRaw (object: object) was doing weird casting and the compiler does not like when is archiving or profiling, so I think we can check if the object implements the ObjectType in the guard.
``` swift
private func registerObjectNotification(_ notificationKey: UnsafeRawPointer, name: Notification.Name, toObserver observer: AnyObject, callback: @escaping (_ monitor: ObjectMonitor<ObjectType>, _ object: ObjectType) -> Void) {
cs_setAssociatedRetainedObject(
NotificationObserver(
notificationName: name,
object: self,
closure: { [weak self] (note) in
guard let `self` = self,
let userInfo = note.userInfo,
let object = userInfo[String(describing: NSManagedObject.self)] as? ObjectType else {
return
}
callback(self, object)
}
),
forKey: notificationKey,
inObject: observer
)
}
```
The same for ListMonitor
``` swift
internal func registerObjectNotification(_ notificationKey: UnsafeRawPointer, name: Notification.Name, toObserver observer: AnyObject, callback: @escaping (_ monitor: ListMonitor<ObjectType>, _ object: ObjectType, _ indexPath: IndexPath?, _ newIndexPath: IndexPath?) -> Void) {
cs_setAssociatedRetainedObject(
NotificationObserver(
notificationName: name,
object: self,
closure: { [weak self] (note) -> Void in
guard let `self` = self,
let userInfo = note.userInfo,
let rawObject = userInfo[String(describing: NSManagedObject.self)] as? ObjectType else {
return
}
callback(
self,
rawObject,
userInfo[String(describing: IndexPath.self)] as? IndexPath,
userInfo["\(String(describing: IndexPath.self)).New"] as? IndexPath
)
}
),
forKey: notificationKey,
inObject: observer
)
}
```
after the correction my app is archiving successfully @sidmani, just I want to know @JohnEstropia if this is a valid fix and doesn't affect to something else, it seems that my app runs perfect but I'm not using ListObserver or MonitorObserver, so just let me know any comment
Thanks for investigating this. I hit this problem in the one of my projects as well and I'm still looking for an actual fix inside the cs_fromRaw() method. The issue is that the compiler doesn't like it when you cast an object to it's own type (which happens on optimized builds due to inlining). @SoyArpad 's code above works because of the extra type-check, which prevents the optimizer from inlining. We can do that for all cs_fromRaw() calls but other usage of the method might still break.
If I can't find a better workaround by the end of the week we'll go with the workaround above.
@JohnEstropia commented on GitHub (Sep 22, 2017):
Thanks for investigating this. I hit this problem in the one of my projects as well and I'm still looking for an actual fix inside the `cs_fromRaw()` method. The issue is that the compiler doesn't like it when you cast an object to it's own type (which happens on optimized builds due to inlining). @SoyArpad 's code above works because of the extra type-check, which prevents the optimizer from inlining. We can do that for all `cs_fromRaw()` calls but other usage of the method might still break.
If I can't find a better workaround by the end of the week we'll go with the workaround above.
@sidmani @SoyArpad I made an edit and it's on the prototype/Swift_3_2 and prototype/Swift_4_0 branches. Let me know how it works for you.
@JohnEstropia commented on GitHub (Sep 22, 2017):
@sidmani @SoyArpad I made an edit and it's on the `prototype/Swift_3_2` and `prototype/Swift_4_0` branches. Let me know how it works for you.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Originally created by @sidmani on GitHub (Sep 10, 2017).
In ObjectObserver.swift (line 325) and ListMonitor.swift (line 714),
ObjectType.cs_fromRaw(object: rawObject)causes a segfault, but only when profiling, not regular building. The strange thing is I can't replicate the issue in the demo project. Do you have any idea what causes this? Commenting out the callback invocation fixes the problem.@sidmani commented on GitHub (Sep 10, 2017):
Here's the output:
@JohnEstropia commented on GitHub (Sep 10, 2017):
Which CoreStore branch are you using?
@sidmani commented on GitHub (Sep 10, 2017):
prototype/swift_4
@JohnEstropia commented on GitHub (Sep 10, 2017):
Thanks, will look into it
@sidmani commented on GitHub (Sep 12, 2017):
@JohnEstropia I made a mistake, the
[weak self]is to blame. Both that and[unowned self]cause a segfault. I still don't know why though.@JohnEstropia commented on GitHub (Sep 12, 2017):
@sidmani Are those [weak self] and [unowned self] within CoreStore's source file? If it's in external code, can you show an example pattern this occurs?
@sidmani commented on GitHub (Sep 12, 2017):
Yeah, they're in CoreStore's source (line 317 in ObjectMonitor.swift, for example). I'm debugging this right now, and by replacing the callback at line 325 with a function call to a temporary function:
I get the compiler error:
Cannot convert value of type 'ObjectMonitor<D>' to expected argument type 'ObjectMonitor<_>'. In theory there should be no difference between calling a closure and a function with the same input and return types, so I think this is the issue. Not sure how to fix yet.@SoyArpad commented on GitHub (Sep 21, 2017):
any update on this @JohnEstropia? im getting the same error while I'm trying to Archive, Thanks
@SoyArpad commented on GitHub (Sep 21, 2017):
it seems that ObjectType.cs_fromRaw (object: object) was doing weird casting and the compiler does not like when is archiving or profiling, so I think we can check if the object implements the ObjectType in the guard.
The same for ListMonitor
after the correction my app is archiving successfully @sidmani, just I want to know @JohnEstropia if this is a valid fix and doesn't affect to something else, it seems that my app runs perfect but I'm not using ListObserver or MonitorObserver, so just let me know any comment
@JohnEstropia commented on GitHub (Sep 22, 2017):
Thanks for investigating this. I hit this problem in the one of my projects as well and I'm still looking for an actual fix inside the
cs_fromRaw()method. The issue is that the compiler doesn't like it when you cast an object to it's own type (which happens on optimized builds due to inlining). @SoyArpad 's code above works because of the extra type-check, which prevents the optimizer from inlining. We can do that for allcs_fromRaw()calls but other usage of the method might still break.If I can't find a better workaround by the end of the week we'll go with the workaround above.
@JohnEstropia commented on GitHub (Sep 22, 2017):
@sidmani @SoyArpad I made an edit and it's on the
prototype/Swift_3_2andprototype/Swift_4_0branches. Let me know how it works for you.@SoyArpad commented on GitHub (Sep 23, 2017):
it works, thank you @JohnEstropia