Is there a maximum size of executables or executables + shared objects on the iPhone? I've been developing an app that has been crashing on startup or early in execution with SIGSYS. Removing code from the program has helped, though structuring data so the code is simply not executed does not.
This could be memory corruption, of some kind, however when I compiled with -Os rather than -O2 or -O3 the size of my executable goes down from 5.15MB to 3.60MB and the application runs perfectly. I also have a bunch of libraries I use, of course.
I'm wondering, is there a limit on the size of executable code on the iPhone? Or am I just 'getting lucky' and masking memory corruption when I use -Os?
If there is a maximum size, there's no way you are hitting it with a 5.15 or 3.60 MB app file. You have a different bug in your app.
You are getting lucky.
You're probably just running out of memory. Are you getting memory warnings?
There is a maximal executable size for delivery via the app store but the hardware itself imposes no unusual restrictions.
Your problem is most likely in one of your libraries. Which, based on your description of the complexity of your app, is not a helpful observation on my part.
Given the pattern with the compiler options, I'm going to take a wild, wild guess that you've got library that has a problem and the tighter compile causes that code to be excluded.
Under the heading of a longshot, you might also want to take a look at resources such as images as well. I've seen a couple of case in the past couple of years in which seemingly innocuous resources have trigger fatal errors when they loaded.
I have hit exactly the same problem. In some tens or hundreds of C++ kloc I never had any problems. Now I essentially copy&pasted a class and renamed two buttons and I get an access violation at startup.
None of the new code is ever executed, just linked in because I take the address of a function. The newly linked compilation unit does not rely on a single static symbol from the outside that could cause background code execution.
The debugger does not point to a useful location. My executable is at around 3.6 MB.
Related
I am trying to create a custom keyboard in iOS 10 that acts like a T-9 keyboard. When switching to my custom keyboard, the app extension reads in a list of about 10,000 words from a txt file and builds a trie out of them.
However, I keep getting a "SigQuit" error when I first try to use the keyboard. Rerunning the keyboard right after it failed seems to usually work. Xcode doesn't give me any explanation for why it failed other than the SigQuit error on some assembly code line.
So, my question is, for what reasons might Xcode throw a SigQuit error? I have tried debugging to no avail, and googling SigQuit does not seem to return any useful information. I considered that my keyboard is using too many resources / taking up too much time on startup, but I checked the CPU usage and it peaked at less than 1%. Similarly, the memory used was something like 25mb which doesn't seem terrible.
Keyboard extensions have a much lower memory limit than apps. Your extension was likely killed by the operating system.
See: https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/ExtensionCreation.html
Memory limits for running app extensions are significantly lower than
the memory limits imposed on a foreground app. On both platforms, the
system may aggressively terminate extensions because users want to
return to their main goal in the host app. Some extensions may have
lower memory limits than others: For example, widgets must be
especially efficient because users are likely to have several widgets
open at the same time.
Yeah, seems like you have to Run, then Stop, and it'll run fine on the simulator or device.
I work on an average (~ 20k lines of code, Objective-C mixed with C++), and I am figthing to hunt down an EXC_BAD_ACCESS error.
I have tried all the common techniques (like enabling NSZombie, guard edges,etc.) So far, I have ruled out the possibility to access a released object, and the double-free error.
It seems that something writes on a memory space where it shouldn't. But, as many memory errors, it's not happening all the time, and it's not crashing always in the same place.
(Sometimes I receive the "object was modified after being freed" message).
Sometimes, the overwritten memory belongs to the allocator, and it crashes on malloc, or on free().
And, of course, some changes in the app may influence the bug's behaviour - if I try to comment out parts of the code, the error appears less often, so it's more difficult to find it.
Finally, I have been looking into using valgrind, but it seems that all those who used it worked on the simulator. but my code must run on the actual device (some code is ARM-specific)
Are there any general tips on how to debug such errors?
Note: The app involves video processing, so the amount of memory used is fairly large.
There are some special tools available on the XCode. You could try to use them in order to analyse your code.
http://developer.apple.com/library/mac/#featuredarticles/StaticAnalysis/index.html
It will produce some warning in case of invalid objects usage so it could help you to find a problem.
If you feel that the C++ code is causing the issue you could copy the C++ out of your iPhone project and create a Mac project. With this you could set up various stress tests. And, you should be able to use valgrind as well.
Hey all, I have a problem and I'd like some advice.
I'm working on a document viewer that's composed of the following major parts:
zip library which unpacks the document container (minizip)
xml library which parses the document (libxml2)
UI code which renders the document on screen
Nothing too complicated or fancy.
On the emulator, everything works beautifully; the viewer performs as expected. I've ran it through Instruments and there are no leaks. ObjectAlloc reports about 5.5 megs allocated over the lifetime of the viewer (that's repeatedly opening my test document over and over).
Unfortunately on the device (iphone 3G, iOS 3.1.2) things aren't as clear. Fairly frequently, repeated opening of the test file causes an out of memory error and the file will fail to open. Initial file opening always works. Even though emulator testing highlighted no leaks and the overall memory footprint was modest, I'm forced to conclude that there IS indeed a leak on the iphone (because why would repeated opening cause out of memory error).
I've attempted to run instruments on the device, but the app stalls (?!) half way through the run, so I actually had no success running Leaks.
I believe that there's a significant leak somewhere that only shows up on the device. So, I'm left with a two options (in no particular order):
Refactor my code in such a way as to avoid using zip library. That would eliminate a potential source of leaks. Time consuming and inconclusive.
Reformat and reinstall everything on my phone (maybe there's something that's causing a problem there). Pretty much as above, time consuming and sucks losing my phone data. Maybe it'll let me run Leaks though.
As you can see, I'm reaching here. Is there anything obvious that I'm missing?
Thanks in advance guys.
Maybe, you should try to run not Leaks, but Allocations Instrument on your device, and to search leaks with it (manually)?
+ (maybe this sounds stupid) Remove app from the device and repeat Clean-Build-Run with Leaks (why not?).
About manual leaks search.
Just start the Allocations Instrument and, while using your app, do every action for several times (for example - press button twice or more; navigate to some panel and back for several times - and so on). Memory should increase significantly only once or increase on action start and decrease on action end (of course, some divergences are possible, but they should be reflected with small amounts of memory). You will see it on graph.
Also make heaps (in Instruments' left panel while Allocations Instrument is selected there is a button for this) - they will help you to detect "still alive" objects that were considered as destroyed (there will be a lot of objects, but the first and easiest step is to check objects of your own classes).
Sometimes the project compiles, and sometimes it fails with
"Out of memory allocating 4072 bytes after a total of 0 bytes"
If the project does compile, when it starts it immediately throws a bad access exception when attempting to access the first (allocated and retained) object, or, throws an error "unable to access memory address xxxxxxxx", where xxxxxxxx is a valid memory address.
Has anyone seen similar symptoms and knows of workarounds?
Thanks in advance.
If compilation or linking is failing with an out of memory error like that, it is likely one of two issues.
First, does your boot drive or the drive that you are building your source on have free space (they may be the same drive)? If not, then that error may arise when the VM subsystem tries to map in a file or, more likely if boot drive is full, the VM subsystem tries to allocate more drive for swap space.
Secondly, is your application just absolutely gigantic? I.e. is it the linker that is failing as it tries to assemble something really really large?
There is also the possibility that the system has some bad RAM in it. Unlikely, though, given that the symptoms are so consistent.
In any case, without more details, it is hard to give a more specific answer.
I've seen this, it is not usually an actual memory error...(of your code)
what is happening is that you have your Xcode target Build settings "optimization level" set to Fast, or faster, or fastest..
there appears to be a bug in there somewhere, set it to none, or try the Os, or O3 (i don't think fastest is effected)..
this will very likely solve someones problem that comes across this thread. for sure try "none" first... this will confirm that this is what is happening in someone's case that sees this...
i can tell that McPragma is having this problem for sure, because he/she describes changing from debug to release, and this causes it (debug is already set to none) and release is set to something else... when that is the case... for sure it is that particular build setting...
I have an iPhone app that is running great in the simulator. It responds well to the memory warnings by getting rid of everything that is not absolutely essential. When I run it on the device, it runs well. But after a certain amount of usage it crashes with error code 101 - which, from what I can tell, is the OS killing it due to memory usage. I can see the memory warning (I'm logging it), and my app responds to it, but dies shortly thereafter.
If I look at the app in Instruments (either on the device or in sim), it doesn't find any leaks. In addition, the net memory usage is in the range of 600-700k bytes. Transitioning from the different views of my app increases memory usage (as expected), but when the views and controllers are released and dealloc'd, the memory usage never quite goes as low as it was. However, the addition is usually only something in the range of 1000-2000 bytes. So while Leaks shows me no leaks, I suspect there is an issue somewhere. I've also looked at all of the objects I'm allocating, and all of them seem to be reclaimed as expected. The only objects I see that keep increasing are GeneralBlock-N (where N is some number)
Should I not pay any attention to Instruments net usage figure? What would be the next steps in trying to diagnose the issue?
ADDED: I'm not making any calls to malloc() or any CoreFoundation libraries that would return a buffer that I'm responsible for. The only non-Obj-C calls I'm making are logging statements to NSLog.
One quick thing to try is running the Clang static analyzer. This will find some, but not all, issues in your code that you might be missing. It checks the code at compile time, so it's by no means infallible, but will almost certainly find most glaring problems.
You should also run your application with the memory monitor instruments to see overall system usage on the device.
Leaks only finds memory that is not referenced by anything, but still retained.
What you are seeing is that you have left memory retained, and still referenced by something.
One thing to look for especially, is that if you have passed a reference of a class to something else as a delegate that you free it in your dealloc method.
Similarly, if you have subscribed to any notifications you should unsubscribe in viewWillDisappear: (if you use the general unsubscription method in a view controller do not forget to re-subscribe to the memory warning notification.
Timers are the same way, deactivate them when a view goes away and re-enable them when the view comes back (unless of course you need a timer running the whole time your application is running).
Basically be suspicious of anything you give a reference of a class to, and try to figure out how you might eliminate that link whenever possible (either in dealloc or viewWillDisappear: or both).
Here's a summary of what I've learned (thanks to some excellent answers and comments):
Object Allocation is NOT the same as Memory usage. The answer to my question about ObjectAlloc's net bytes element is that you shouldn't be paying attention to it - at least not when determining issues with the amount of memory you are using or whats causing it to crash. It doesn't reflect the true memory usage of your application.
My amatuerish guess is that ObjectAlloc only shows you the memory taken up by the direct object itself. So if you have an UIImageView, it takes up just a handful of bytes to store the various properties, but it might be pointing to an image in memory taking up a bunch of space. Therefore, looking at ObjectAlloc is helpful only in making sure you're not creating and keeping objects around, it won't give you an idea of how much memory you're using or how much you can use before crashing.
MemoryMonitor will give you the total memory usage. You can constrain it to viewing only your app's usage by using the search tool in the bottom right of the Instruments window.
Both ObjectAlloc and Memory Monitor (as well as the Leaks tool) are plugins for Instruments - just in case thats not obvious to someone else. You can launch Instruments from within XCode by doing Run -> Start with Performance Tool. Once inside of Instruments, you can open the Library and add new plugins to monitor different aspects of performance.
One thing to look for is circular references.
(I don't want this to sound patronising - just want to make sure I'm being clear:) If object a refers to object b and object b refers to object a, there may not be a reported "leak" because all the memory is still referenced - but this may be an orphaned island of objects, seperated from your app and never reclaimable. Of course it may involve more objects ( a refers to b, b refers to c, c refers to a, etc).
If you're building up a graph of objects somewhere, and there are any back or cross references, be sure to break the circles if you release the root (there are different ways of doing this. The simplest is probably to make sure each class in question has a releaseAll method, or similar - which calls releaseAll on it's child objects, then releases the child objects - but this isn't always the best solution).