I'm working on an app that is recording data via Bluetooth, but it intermittently crashes after hours of collecting data (making it hard to track down the bug).
The logcat output isn't very helpful:
http://i.imgur.com/EalnX.png
There are no exceptions thrown and no clues for what caused the process to be terminated.
How can I figure out what went wrong? Is there an exception being thrown that isn't being shown by logcat? How can I track this bug down?
Signal 9 is SIGKILL, which will terminate a process immediately (no handlers inside the process will run). From the log line, the process is killing itself, so its not an external agent that is issuing the SIGKILL.
My guess (and its really a guess) is that the memory management code running inside your process (as part of the infrastructure, not code that you wrote) is deciding that you've exhausted some resource and the only recourse is to die. I would expect there to be more messages before this point is reached in the log, so it may be worth browsing the log history to see if there are useful warnings from the process before this point.
The line immediately before this is a GC log, which implies that some sort of memory resource is running low. But it looks like the heaps are not full, so failing allocations seems unlikely. You can still get allocation failures if the object being allocated was too large to fit on the heap, or fragmentation prevented it from being allocated. I'd expect to see more relevant log messages in this case, though.
I think capturing more of the log (perhaps filtering it by your app's PID if necessary) will help you make progress.
In my case there was no warnings or any clues in the log.
Eventually I found that my problem was that one of the activities I was going into (lets say Activity X) was registering to a broadcast receiver but never unregistered from it.
Therefor by closing the activity (Activity X) and coming back to it caused registering Again to the same broadcast receiver - which caused the mess!
Simply adding unregisterReceiver(mybroadcast); (in Activity X) solved it.
(I added mine to onDestroy. make sure you unregister in the right location).
And if you are super desperate I recommend seeing this slide share which explains Android crash debugging your errors.
this problem happens when using RXjava and not implement the onError callback method
Related
I've had a sudden spike of ANRs lately, seems like October 5th is when they really started spiking up. They are affecting my latest release that is from around that date but they are also affecting my previous release that is from earlier in September. For that earlier release I can see that the ANRs really started on the 5th.
For my top two ANR traces, I don't see a single line that involves my code and the info in them isn't really useful. I'm including a full screen printout of one of the traces, they are all a bit different but they have some of the same stuff. Particularly I noticed most of them have a gms measurement call going on. While I haven't updated gms recently.
So my question is, how do I go about troubleshooting a trace like this?
Trace link https://imgur.com/JYaU9Uo
Thanks.
Here is are couple of clues from the Traces:
CountDown latch is used. So one of those threads, that is using latch is taking a long time to complete. That is causing the Main thread to be blocked.
Shared Preferences is being edited
A service is being stopped
Is there something of this phenomenon thats happening in your app?
"A service is being stopped, and shared preferences is being edited".
Countdown latch :
A java.util.concurrent.CountDownLatch is a concurrency construct that allows one or more threads to wait for a given set of operations to complete.
A CountDownLatch is initialized with a given count. This count is decremented by calls to the countDown() method. Threads waiting for this count to reach zero can call one of the await() methods. Calling await() blocks the thread until the count reaches zero.
#casolorz : Debugging ANR is a challenge. The ANR trace you have is just the state of all threads in your Application Process when the ANR has occurred. It is not as straight forwards as debugging a crash.
Here are some ways that you can debug
Method 1
See the state of the Main Thread.
If the main thread is Waiting, then figure out what is making it wait. It may be some other thread that is making it to wait. You can find out the culprit by tracking down the thread identifier. You might see something like "Waiting because of a resource held by Thread tid= ". tid should help you to navigate to the culprit.
With tid, you can follow the trail as long as possible till you reach a dead end.
If method 1 does not give you a headway, try this
Method 2 : Come up with a Hyphothesis.
Find out whats happening to the Main thread
In your case, the app is getting launched. You can see Zygote getting initialised, which confirms this hypothesis.
Once you know that the ANR is happening at App launch, see what is happening at app launch which would relate to I/O or Network.
This could be like accessing a SharedPreference which is quiet heavy(Say 1 mb which is a bad thing. You need to consider making the shared pref thin).
Or this could be an SDK that you are initialising. You can profile your code using Traces, and this would give you a fair idea of something that is taking a long time to execute.
Sometime this might be totally unrelated to your application. I have seen this occur.
Debugging ANR's are quiet challenging and its interesting too.
1.) It may be because of you are running SharedPreferences apply() method very frequently which are spanning so many threads and all threads are trying to write to the same shared preference file which are queued and while onPause() method is called all these operations are blocking to finish which is causing ANR.
2.) If you are using commit() for Shared Preferences then it will be blocking call on main thread for all previous apply() asynchronous operations for the same SharedPreference which may cause ANR on main thread.
3.) May be some big data is saved in Shared Preference because of which other commit()/apply() are placed in queue and waiting for their turn to write to the I/O file and can cause ANR once onPause() is called since all these commit() and apply() operations need to be finished before onPause() finished.
I'm getting following exception as soon as I want to show a widget and start listening:
// the relevant stack trace, the rest is comming from my code
// before the code line I posted below
java.lang.RuntimeException: system server dead?
at android.appwidget.AppWidgetHost.startListening(AppWidgetHost.java:189)
at com.my.app.utils.WidgetUtil.a(SourceFile:231)
...
android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:503)
at com.android.internal.appwidget.IAppWidgetService$Stub$Proxy.startListening(IAppWidgetService.java:481)
at android.appwidget.AppWidgetHost.startListening(AppWidgetHost.java:185)
at com.my.app.utils.WidgetUtil.a(SourceFile:231)
...
The source in my code is following code line:
mAppWidgetManager = AppWidgetManager.getInstance(context);
mAppWidgetHost = new AppWidgetHost(context, R.string.app_name);
mAppWidgetHost.startListening(); // <= this line leads to the crash
Observations
my app is working normally on a lot of phones (all but one actually)
above crash only happens on one users device (SM-N910C (Samsung Note 4), Android 6.0.1)
the user says, those widgets work fine in his launcher
Does anyone has an idea what could cause this? Is this something I can solve in my app? The user says widgets are working fine in his launcher...
So, a simple Google search led me to this definition of a DeadObjectException :-
The object you are calling has died, because its hosting process no longer exists.
From this, it is obvious that you're getting this error because the process that's hosting mAppWidgetHost has been killed off.
The question now is that why are you getting this error. Overriding and logging onDestroy() to monitor it could be useful, and definitely is worth a shot. But, since its working on all devices except for one, its more than likely that there's nothing wrong with the onDestroy() method. Instead, the OS is killing the process off before you can access the object.
So, now why is the OS doing that? This question had me balled up for the longest time. I still do not have a clear answer or solution to this despite a bevy of Google searches with all kinds of related to the problem. But, after spending a considerable amount of time searching, I noticed a peculiarity - most of the issues with this exception, such as this, this and yours happen with Samsung devices.
My guess is that Samsung's underlying architecture leads to this problem. And, while I do not have a reason why this happens or a plausible solution even after a lot more searching, this could still be a start to find a work around targeting Samsung devices.
UPDATE
I searched a bit more and came across this answer. Take a look at the last comment by the question author on the question :-
Finally it is working fine just by a line of code in manifest file, here it is android:hardwareAccelerated="false" If anybody get the following kind of errors please try by adding the above line signal 11 (SIGSEGV), code 1 (SEGV_MAPERR)
I don't know the logic behind this or if it would work or not. Just sharing it with the hope that it could help you - even in the minutest form.
DeadObjectException :
The object you are calling has died, because its hosting process no longer exists.
Possible Solutions:
1) Override your service's onDestroy() method and watch what event flow leads to it. If you catch DeadObjectException without going through this method, your service should have been killed by the OS.
2) by removing Typeface , this might be because of ttf which i was using from assets folder Please try comment the typeface and test it hope it will work for sure
3) put all your code inside the onCreate. From there you will see what is the culprit like a NullPointerException for example but your code will run smoothly already.
I have a bug that I am unable to reproduce on command or from the emulator, but seems to happen after leaving the app alone for a long time in the physical device.
All fragments continue to be responsive, but messages seem not to be passed from one fragment to another.
My best guess, is that some sort of garbage collecting might be breaking the links. Very vague question, but I'm desperate:
What could lead to such a bug that happens "after a long time" (ie, hours)? What should I be looking for, in the code I write, if I suspect that the app isn't "restoring" successfully?
Also, adb logcat when physical device is connected via usb debug should show up any error messages that I print with log.e(), correct?
For future googlers and other novice coders -- Today i learned, Save references to fragments you create. Or, don't make fragments local variables. I didn't need the reference to the fragment, only the contained view. As a result, the fragment got garbage collected and a new one recreated on restore, hence breaking the communication link.
Sound like the activity (/fragment) is not save in the memory anymore - Android framework may destroy your activity any time it's in the background or backstack, and you should write your activities so they behave correctly when this happens. In order to beat this override onSaveInstanceState method.
You can cause it happen and try to reproduce it via developer options -> Don't keep activities
For some strange reason, which I'm not entirely sure why, I'm getting not only an ANR for my application, but also of the entire systemui. It's so bad that I HAVE to reboot, and after rebooting it has to "Optimize" all of my apps like it corrupted something (anyone have an explanation as to why this happens?).
I'm assuming that parts of my code are so bad that they're causing this, but should even malicious code be able to overload the systemui? Anyway...
What I am doing is that I'm attempting to launch a service to handle screen recording. The activity (from a fragment) asks for permission (which is obtained, and I see the Screencast icon in the top right corner of the screen), then it binds a service which handles any state changes. What I mean by state changes is this...
States:
Dead - Means it needs to be initialized and prepared
Alive - Means it needs to be start and is fully initialized/prepared
Started - Means it is currently recording.
Paused - Means it will start a new video after starting again, which it will combine all temporary videos into one (haven't worked out that details yet).
Stopped - Means combine any and all files into one, then send the URI through an intent in a broadcast (haven't gotten this far yet).
It goes from Dead -> Alive -> Started <-> Paused -> Stopped -> Dead. At least that's the overall plan. I plan on having a floating button that acts as remote for controlling the service, and hence broadcasting on a receiver (local) to my fragment which is waiting for it to be finished.
Now, enough of what I intend to have, lets get into what I have right now. It's kind of a mess, I've never done this stuff before, hence why I'm asking on here. Trust me when I say that I have tried a lot of stuff, and the unfortunate bit is, the only way to test out a new solution is to reboot and wait 15 minutes while Android optimizes everything again. Now I understand it's a "Long" code-segment, but I'll say that one place it crashes is stopRecording(), at line 216.
Code here.
Let me know if I should make any changes.
Lastly: Should any of this be run on another thread? Could that be the issue? Why doesn't the app crash only instead of systemui?
I have an Android app that uses a timer to call an AsyncTask every 5-10 seconds (using java.util.Timer and java.util.TimerTask). The AsyncTask gets image data from an Amazon AWS S3 database, and loads an ImageView for the main UI Activity.
This works fine for an hour or two, but then I get a cryptic error message and the app gets killed. The error message comes from "Looper" and says either:
Could not create epoll instance. errno=24
or
Could not create wake pipe
A search on the web seems to indicate the problem may have something to do with file descriptors (too many open file descriptors ?). I've gone through the code, but don't see any place where files, streams, or connections aren't closed.
When the app is killed, logcat has a message from AndroidRuntime that says:
FATAL EXCEPTION: main
Does anyone have a clue about these messages, or how to fix? Thank you!
possible memory leak. Use Leakcanary to detect which exact part of the code is creating this.
I got the same bug in my code when I used an alarm to trigger a task too quickly.
I fixed it by changing my code so that it only got added to the alarm to be run again after the average run time of the method (plus a little extra time just in case). If you add tasks more quickly than they finish executing then you'll fill up the Looper eventually which throws the error.
Essentially all that a Looper is is a queue of things to be run by the thread from my understanding.