From time to time my users find this error:
myapp(7383,0x1a1471000) malloc: * mach_vm_map(size=67125248) failed (error code=3) error: can't allocate region set a breakpoint in malloc_error_break to debug 2017-04-06 20:33:58.152 myapp[7383:3724816] Terminating app due to uncaught exception 'NSMallocException', reason: ' NSAllocateObject(): attempt to allocate object of class 'IOSByteArray' failed' * First throw call stack: (0x183386db0 0x1829ebf80 0x183386cf8 0x183c6b34c 0x10076e6e4 0x10097d3ec 0x10097e35c 0x100977dd4 0x100977bd8 0x100978ff8 0x10096c950 0x10099685c 0x100997360 0x100979ca4 0x100976dcc 0x1002ec30c 0x100332fe4 0x100332e18 0x1003740c4 0x1004070f8 0x1004064ac 0x1021089b0 0x10210806c 0x1021089b0 0x102107710 0x1004072d8 0x1021087ec 0x1004071b0 0x102126bbc 0x10207b2d8 0x10207b374 0x188613dc4 0x1886d17d4 0x18878f0c8 0x18879ca80 0x1884ce5a4 0x18333c728 0x18333a4cc 0x18333a8fc 0x183264c50 0x184b4c088 0x188546088 0x100382a60 0x182e028b8) libc++abi.dylib: terminating with uncaught exception of type NSException
The problem is that I can not find the callstack of the error. I'm using XZ java lib ported into objc lib using j2objc application. So, I can use this lib but I can't catch this error.
Google Analytics helps me and shows this line:
"&exd" = "NSMallocException\nTrace:\n\nNSAllocateObject\nIOSByteArray_NewArray\nOrgTukaaniXzLzLZDecoder_initWithInt_withByteArray_\nnew_OrgTukaaniXzLzLZDeco";
So, It seems there is an error occurs:
void OrgTukaaniXzLzLZDecoder_initWithInt_withByteArray_(OrgTukaaniXzLzLZDecoder *self, jint var1, IOSByteArray *var2) {
NSObject_init(self);
self->start_ = 0;
self->pos_ = 0;
self->full_ = 0;
self->limit_ = 0;
self->pendingLen_ = 0;
self->pendingDist_ = 0;
JreStrongAssignAndConsume(&self->buf_, [IOSByteArray newArrayWithLength:var1]);
if (var2 != nil) {
self->pos_ = JavaLangMath_minWithInt_withInt_(var2->size_, var1);
self->full_ = self->pos_;
self->start_ = self->pos_;
JavaLangSystem_arraycopyWithId_withInt_withId_withInt_withInt_(var2, var2->size_ - self->pos_, self->buf_, 0, self->pos_);
}
}
But I can't find this error using swift:
do {
// ............
let inxz:OrgTukaaniXzXZInputStream = try OrgTukaaniXzXZInputStream(javaIoInputStream:in_)
// ..........
} catch {
print(error)
}
Please, help me
Swift's try/catch is completely separate from ObjC exceptions like this one. Those can only be caught with ObjC using @try
and @catch
. It is not possible to do in Swift.
That said, ObjC is generally not exception-safe. You have to be very careful using them, and in almost all cases the correct behavior after an exception is to crash the program. In this case, wrapped around exactly one call to a bridged function, it may be possible to effectively catch and deal with, but doing it correctly is a fairly subtle skill and not recommended if you can avoid it.
Almost certainly the reason for this error is that you're trying to allocate something too large. Rather than trying to catch the exception, I would look into why the object is so large and address that. In particular, I'd look at how large var1
is and make sure it's in a reasonable range. Also make sure it's not negative. The fact that you're using jint
suggests that you might be seeing a mismatch with your integer types which I would absolutely expect to cause this kind of crash.