I have been having a bit of a bug while testing on iOS 6 with my current iOS 5 app.
We have experienced a lock up on a method return for an innocuous method that internally used blocks, but not as properties. The issue is that calling the method works, so does every line of code within the method (including the block utilizing code)
I tried using [block copy] before calling the block, but there was absolutely no change.
turns out the function definition of my code was declared in an internal interface and did not have a return type.
Here are some graphics to illustrate this issue.
The Initial Error
The Stack Track
The Method in Question (isolated from self to determine the issue exact location)
The Function Implementation (this is what is called, and returned)
The Definition in the Private Interface
I decided to look at the function call, and noticed it returning (id) rather than void
And Finally the only code change that alleviated this bug.
Explanation
This bug reared its ugly head when my client called me saying our app does not run on ios 6
I was forced to download iOS 6 and Xcode 4.5 for testing this out.
I did indeed crash every time the app was run.
After hunting down this bug on stack overflow among other sites linked to by Google, I tried the block issue that some others are experiencing. And did a copy wherever I could to try to alleviate the issue of retained object falling off the stack.
I was not using block properties so I just called copy on the blocks themselves.
This did not help.
Finally with another developer going over it with me. I was stepping back and looking at it from another angle, and decided to try to determine what the heck was being retained.
It turned out the result of the function was being retained. And the only way I figured that out was to look at the value that auto complete showed me as the return type.
I knew the return type to be void, however it was telling me that the return type was id and that is what sparked the investigation into the method definition.
I hope this helps others that have this issue as I spent about 2 hours hunting it down and it turned out to be a semantic issue between a result type that should never have existed.
Related
I remember from watching CS193P from Stanford University on YouTube (yes, I'm a smart bunz)... that there's this thing called a memory leak or "retain cycle" -- something really bad -- that can happen when you do things like this:
referencing self. within a completion block
referencing self. within a timer callback
referencing self. within a SyncQueue.sync() method
referencing self. within a DispatchQueue.main.async() method
The solution generally seems to be to use the "weak self" reference instead.
I have 104 of these asynchronous self. references in my ViewController which is why I am a little worried.
HOWEVER... this app is a single-page app... and ALL these self. references are pointing to this main ViewController (or one of its permanent sub-views) which is always there, never dismissed, and never "popped from the stack."
My app seems to work fine... and I don't see the total memory usage going haywire or anything... So does that mean I can leave my (ViewController) code as-is in this regard?
Thanks for help!
Here are two situations where you may regret not fixing your code:
If the device runs low on memory when your app is in the background, there are aspects of your view controller and its views that can be deleted. See this (admittedly old, but still interesting) article. This could easily affect your app more significantly in a future iOS version, or maybe even now depending on what your code is doing.
Jump 6 months ahead, where you or someone else on your team is borrowing some of your code for another app. You (or they) will likely get burned. Best to just fix the code now. The fixes shouldn't cause a major refactor, but if you find one that does, you could always insert a big warning comment at that line instead.
So I'm using AWS Cognito to authenticate my users from my iOS application. However in a small bit of code, I've narrowed down an extremely odd problem while making some minor changes.
I noticed that I was receiving this error:
Unable to refresh. Error is [Error
Domain=com.amazonaws.AWSCognitoCredentialsProviderErrorDomain Code=1
"identityId shouldn't be nil"
UserInfo={NSLocalizedDescription=identityId shouldn't be nil}]
After debugging, I've noticed the identityId actually does not get set:
_identityId = [jsonDict objectForKey:#"IdentityId"];
self.keychain[EncryptionKeyKey] = self.identityId;
return [AWSTask taskWithResult:nil];
Though I clearly set it in the above code block, and checked to make sure that [jsonDict objectForKey:#"IdentityId"] did produce some value, I found through the debugger that a "po self.identityId" before and after the assignment is still nil. NSString isn't something that needs to be allocated, and what's weirder is that this used to work. I switched some statements up because of my current use of UICkeychainstore but that shouldn't affect anything. In addition, I disposed of my changes and saw that the problem still exists. Please let me know if you have any ideas.
I'm also noticing this error shortly after the previous error:
This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes. This will cause an exception in a future release.
any ideas would be very helpful
Turns out that I had both a login method and a getToken method. In the getToken method I wasn't doing something right based on some changes I had made to the code to use keychain instead of nsuserdefaults for security reasons. After fixing the getToken it worked. After further debugging though, I saw that identityId still doesn't get set regardless of it working or not. I guess it might be some sort of block variable s.t. the assignment doesn't happen immediately. At least that's my theory. All in all it works though.
From time to time, Xcode Crashes comes up with a crash that i cannot understand. I pasted the xccrashpoint to gist
It states, that Thread 12 crashed somewhere in CoreGraphics called by CorePDF, called by QuartzCore drawing some layers. This seems like OS-called code, maybe via thread 1 which is doing _saveSnapshotWithName. So i assume, that this happens when closing the app.
Does anyone have at least a rough idea what is going on here? Maybe someone saw something similar before and can give a hint about what is crashing…
There is nothing special in the app that would cause dramatically wrong behaviour when leaving the app (-> when a screenshot ist taken).
Exec bad errors occur when an attempt is made to access a object or memory location which is not yet initialized.
There might be a problem with an object which you are not defining global.
Check if there is any object you defining and initializing in a method and trying to access out of the scope.
For more details related to errors and crashes, please go through below link.
http://www.raywenderlich.com/10209/my-app-crashed-now-what-part-1
An application in the field is getting this message intermittently:
I am not able to reproduce this on my machine. I have also traced what I believe is the relevant code and can't find any access to uninitialized objects.
I've never had to deal with this kind of problem.
I did a build with madExcept and unfortunately the program does not crash once it is bundled.
Any opinions on madExcept vs EurekaLog for finding this kind of thing? I've never used FastMM. Would it be useful in his situation? (Delphi 2010) Any suggested flags to set in FastMM? Any other recommendations?
Note the very low address you are attempting to read. This sort of error almost certainly means you attempted to dereference a nil pointer even if you can't find one.
Given your description of the behavior I would suspect you've got a memory stomp going on--something is blasting a zero on top of the pointer to an object. When you change things you move things around and the stomp moves to someplace harmless.
Turn on both range checking and overflow checking.
Note the offending object must be at least 3C0 bytes in size--this should help narrow it down, most objects will be smaller than this.
What I have done in the past with such errors that only show in the field is put logging checkpoints in--a bunch of lines that display something in an out of the way place--a simple sequence of numbers is fine. Find out what number is showing when it crashes and you know which of you checkpoints was the last to execute. If that doesn't narrow it down enough you can repeat the process now that you've narrowed it down.
With a full map file you can identify the exact point in the code where this occurs. I hope you have a full map file for this image! Subtract $00401000 from the address at which the exception is raised ($007ADE8B in your case) and that corresponds to the values in the map file.
Having done that you know which object is nil and from there it is usually not too hard to work out what is going on.
One of the most common ways for this to occur is when a constructor raises an exception. When this occurs the destructor runs. If you access, in a destructor, a field that has not been initialised, and do anything other than call Free on it, then you will get an exception like this.
Looks like a memory overwrite where changing memory layout (your machine vs field machine or adding madExcept) makes the overwrite change something harmless.
FastMM is great at of making this kind of problems happen more consistently (and finding their source). Download the full version of FastMM, add it as the first unit of your project, and turn on FullDebugMode on its settings.
It might cause the problem to be reproduceable in your machine right away. If not, don't forget to deploy FastMM_FullDebugMode.dll with your application for testing. Keep madExcept on and let it embed the .map file for call stacks.
This happens half of the time when closing my application in which I have placed a TLMDHiTimer on my form in design time, Enabled set to true.
In my OnFormClose event, I call MyLMDHiTimer.Enabled := false. When this is called, I sometimes (about half of the time) get this exception.
I debugged and stepped into the call and found that it is line 246 in LMDTimer.pas that gives this error.
FThread.Terminate;
I am using the latest version of LMDTools. I did a complete reinstall of LMD tools before the weekend and have removed and re-added the component to the form properly as well.
From what I've found, this has something to do with TExternalThread, but there's no documentation on it from Embarcadero and I haven't found anything referencing it within the LMDTools source code.
Using fully updated RAD Studio 2010, Delphi 2010.
What really upsets me here is that there's no documentation whatsoever. Google yeilds one result that actually talks about it, in which someone says that the error is caused by trying to terminate a TExternalThread.
But looking at the source-code for this LMDHiTimer, not once does it aim to do anything but create a regular TThread.
The one google result I could find, Thread: Cannot terminate an externally created thread? on Embarcadero mentions using GetCurrentThread() and GetCurrentThreadId() to get the data necessary to hook on to an existing thread, but the TLMDHiTimer does no such thing. It just creates its own TThread descendant with its own Create() constructor (overridden of course, and calls inherited at the start of the constructor)
So... What the heck is this TExternalThread? Has anyone else run into this kind of exception? And perhaps figured out a solution or workaround?
I've asked almost the exact same question to LMDTools' own support, but it can't hurt to ask in multiple places.
Thank you in advance for any assistance.
TExternalThread wraps a thread that the Delphi RTL didn't create. It might represent a thread belonging to the OS thread pool, or maybe a thread created by another DLL in your program. Since the thread is executing code that doesn't belong to the associated TExternalThread class, the Terminate method has no way to notify the thread that you want it to stop.
A Delphi TThread object would set its Terminated property to True, and the Execute method that got overridden would be expected to check that property periodically, but since this thread is non-Delphi code, there is no Execute method, and any Terminated property only came into existence after the thread code was already written someplace else (not by overriding Execute).
The newsgroup thread suggests what's probably happening in your case:
... you have corrupted memory that causes the TThread.FExternalThread member to become a non-zero value.
It might be due to a bug in the component library, or it could be due to a bug in your own code. You can use the debugger's data breakpoints to try to find out. Set a breakpoint in the timer's thread's constructor. When your program pauses there, use the "Add Breakpoint" command on the Run menu to add a data breakpoint using the address of the new object's FExternalThread field. Thereafter, if that field's value changes, the debugger will pause and show you what changed it. (The data breakpoint will get reset each time you run the program because the IDE assumes the object won't get allocated at the same address each time.)
Is there any chance the code might be trying to Terminate an already Destroyed TThread? This could easily happen if you have FreeOnTerminate set.
I noticed your post while diagnosing a similar (opposite?) error, "Cannot call Start on a running or suspended thread" in the constructor of a component placed on the main form. When I removed the Start(), that error was replaced by more telling errors, e.g. "invalid pointer operation" and "access violation", in the corresponding destructor. The component was trying to manipulate its TThread object after the TThread was Freed, thus leaving things up to Murphy's law. When I fixed that, I was able to replace the Start() call without the "Cannot call Start" error returning.
By analogy, could your problem be that the address of your FExternalThread had been recycled and clobbered before the destructor/Terminate call? In our case, we had a buggy implementation of the Singleton Instance Pattern; but again, FreeOnTerminate also seems like a likely suspect.
[FYI: I'm using I'm using C++ under RAD Studio XE]