问题
I am running my app in Release config and my app crashes when it reaches a certain point. The crash points to this message:
bson was compiled with optimization - stepping may behave oddly; variables may not be available.
bson is dependency used by one (or a few) of my pods.
I have searched SO and understand that adjusting the Optimization level for both project and pods level would help, but these did not work for me since I am running in Release config.
When I run my app in Debug, there were no crashes.
UPDATE:
Here's the crash event:
//Stack 8, in my FeedCell
let pipeline: [Document] = [
["$match": ["source_id": ["$in": sourcesUrls] as Document] as Document] as Document, //<== Here
["$sort": ["pub_date": -1] as Document] as Document,
["$skip": skip] as Document,
["$limit": 10] as Document
]
articlesCollection?.aggregate(pipeline).toArray { result in
switch result {
case .success(let results):
completion(results, nil)
case .failure(let e):
completion(nil, e)
}
}
// Stack 6 in MongoSwift > Document.swift
/// An extension of `Document` to add the capability to be initialized with a dictionary literal.
extension Document: ExpressibleByDictionaryLiteral {
/**
* Initializes a `Document` using a dictionary literal where the
* keys are `String`s and the values are `BSONValue`s. For example:
* `d: Document = ["a" : 1 ]`
*
* - Parameters:
* - dictionaryLiteral: a [String: BSONValue]
*
* - Returns: a new `Document`
*/
public init(dictionaryLiteral keyValuePairs: (String, BSONValue)...) {
// make sure all keys are unique
guard Set(keyValuePairs.map { $0.0 }).count == keyValuePairs.count else {
fatalError("Dictionary literal \(keyValuePairs) contains duplicate keys")
}
self.storage = DocumentStorage()
// This is technically not consistent, but the only way this inconsistency can cause an issue is if we fail to
// setValue(), in which case we crash anyways.
self.count = 0
for (key, value) in keyValuePairs {
do {
try self.setValue(for: key, to: value, checkForKey: false) // <== Here
} catch {
fatalError("Error setting key \(key) to value \(String(describing: value)): \(error)")
}
}
}
}
//Stack 5, MongoSwift > Document.swift
/**
* Sets key to newValue. if checkForKey=false, the key/value pair will be appended without checking for the key's
* presence first.
*
* - Throws:
* - `RuntimeError.internalError` if the new value is an `Int` and cannot be written to BSON.
* - `UserError.logicError` if the new value is a `Decimal128` or `ObjectId` and is improperly formatted.
* - `UserError.logicError` if the new value is an `Array` and it contains a non-`BSONValue` element.
* - `RuntimeError.internalError` if the `DocumentStorage` would exceed the maximum size by encoding this
* key-value pair.
*/
internal mutating func setValue(for key: String, to newValue: BSONValue, checkForKey: Bool = true) throws {
// if the key already exists in the `Document`, we need to replace it
if checkForKey, let existingType = DocumentIterator(forDocument: self, advancedTo: key)?.currentType {
let newBSONType = newValue.bsonType
let sameTypes = newBSONType == existingType
// if the new type is the same and it's a type with no custom data, no-op
if sameTypes && [.null, .undefined, .minKey, .maxKey].contains(newBSONType) {
return
}
// if the new type is the same and it's a fixed length type, we can overwrite
if let ov = newValue as? Overwritable, ov.bsonType == existingType {
self.copyStorageIfRequired()
// swiftlint:disable:next force_unwrapping - key is guaranteed present so initialization will succeed.
try DocumentIterator(forDocument: self, advancedTo: key)!.overwriteCurrentValue(with: ov)
// otherwise, we just create a new document and replace this key
} else {
// TODO SWIFT-224: use va_list variant of bson_copy_to_excluding to improve performance
var newSelf = Document()
var seen = false
try self.forEach { pair in
if !seen && pair.key == key {
seen = true
try newSelf.setValue(for: pair.key, to: newValue)
} else {
try newSelf.setValue(for: pair.key, to: pair.value)
}
}
self = newSelf
}
// otherwise, it's a new key
} else {
self.copyStorageIfRequired()
try newValue.encode(to: self.storage, forKey: key)
self.count += 1
}
}
//Stack 3, MongoSwift > Document.swift
public func encode(to storage: DocumentStorage, forKey key: String) throws {
var arr = Document()
for (i, v) in self.enumerated() {
guard let val = v as? BSONValue else {
throw UserError.logicError(
message: "Cannot encode a non-BSONValue array element: \(String(describing: v)) "
+ "with type: \(type(of: v)) "
+ "at index: \(i)"
)
}
try arr.setValue(for: String(i), to: val)
}
guard bson_append_array(storage.pointer, key, Int32(key.utf8.count), arr.data) else { //<== here
throw bsonTooLargeError(value: self, forKey: key)
}
}
来源:https://stackoverflow.com/questions/61816632/xcode-bson-was-compiled-with-optimization-stepping-may-behave-oddly-variable