I have some problem with an ANR files, I got a SUSPENDED lable in main thread,
somebody say the reason maybe GC , Debugger, infinite loop, so I have try Debugger and infinite loop, and I got the SUSPENDED , but the difference is when I use Debugger to get ANR, I got sCount=2 dsCount=1, and when I use infinite loop to get ANR, i got sCount=1 dsCount=0..
so What does it mean in an ANR file?
Following is the screenshot of the ANR
As you can judge from sources:
dvmPrintDebugMessage(target, " | group=\"%s\" sCount=%d dsCount=%d s=%c obj=%p
self=%p\n",
groupName, thread->suspendCount, thread->dbgSuspendCount,
thread->isSuspended ? 'Y' : 'N', thread->threadObj, thread);
So, to answer your question:
sCount stands for thread->suspendCount, dsCount stands for thread->dbgSuspendCount.
Related
I need to reproduce Application Not Responding (ANR) dialogs from Activity and from BroadCastReceiver.
I tried to create a simple button click:
public void makeANRClick(View view){
while (true);
}
With this code I reproduced ANR on emulator with android 2.3.7. Same code doesn't work on real device with the newest android versions (4+).
Another attempt was as follows:
public void onMakeANRClick(View view){
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
This doesn't help also.
Any suggestions?
Keyword multi threading. Please read this topic http://developer.android.com/training/articles/perf-anr.html
Also there is no way to manage UI components at Broadcast Reciever, Because it is no UI component.
Also there is option in Development Options called "Show All ANR"
Have a look at StrictMode. And this video, too.
"StrictMode is a developer tool which detects things you might be doing by accident and brings them to your attention so you can fix them. "
Also you can check the dump state to check info about your process
https://source.android.com/devices/input/diagnostics.html
I reproduce your code and then pull the 'dumpstate_app_anr.txt.gz'
and this was the result
PID TID PR CPU% S VSS RSS PCY UID Thread Proc
15287 15287 0 83% R 227152K 25152K fg u0_a135 a.stackoverflow mx.syca.stackoverflow
07-03 08:46:12.454 1618 1636 I ActivityManager: Killing proc 12946:mx.syca.stackoverflow/u0a135: force stop
It took about 2 minutes to get the ANR dialog
Hope it helps
I do believe that the best way to perform ANR in java (dalvik) is to perform absurd ammount of calculations, including function calls.
Perhaps something akin to:
Integer useless = 0;
for (i=2147483648;i<2147483647;i++){
useless = Math.random() * Math.random() * Math.random() * Math.random();
}
This will at least, trigger some delay, and ANR on weaker systems.
I have an exception that I'd like to handle, but I cannot tell its origin based on the stack trace (NsdManager.java:338 isn't mine and that files only has 58 lines). None of the files it references are mine.
Is there a way to handle any exception that comes up from the Handler?
E/AndroidRuntime﹕ FATAL EXCEPTION: NsdManager
java.lang.NullPointerException
at android.net.nsd.NsdManager$ServiceHandler.handleMessage(NsdManager.java:338)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:60)
I am using a handler to help discover/rediscover a network based service when WiFi switches on and off.
Edit: Pastie of code
Full Stack Trace
MainActivity
NsdHelper
WifiBroadcastReceiver
WsHelper
NsdManager - Line 338 doesn't exist here, so I don't know what code to wrap in a Try/Catch.
Thanks
Turns out the NSD Manager has some long standing problems
https://code.google.com/p/android/issues/detail?id=35585
jmDNS works much better.
In Eclipse, I notice that Logcat only retains a few dozen entries and deletes the older ones as soon as a new one come in. Is there a way to prevent this? I need my app to run for a long time and not lose any entries because my app eventually hangs or crashes after a few days, and I want to see if something in Logcat has been recorded.
I am not sure if this is the most elegant solution to the problem, but you can always increase the LogCat message size in Eclipse.
Window -> Preferences -> Android -> LogCat -> Maximum number of LogCat messages to buffer
The default is 5000, I believe. You can set it to be very high if you are planning to run your application for a long time.
i think you need to increase this show image
Here's a better solution:
Set the Default Uncaught Exception Handler. Whenever the app crashes, this will be called with the exception. Simply write a log entry saying it crashed then dump the logcat to a file. Finally, make sure you re-throw the exception to make sure the app crashes and funky things don't happen. Note: This is per thread, keep that in mind.
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable ex) {
Log.e("TAG", "---My app crashed just now---", ex);
//TODO: Dump logcat to file
throw new RuntimeException(ex);
}
});
if you want to keep your app running for days.. its better you capture your logs from adb shell.
the common shell command would be :
logcat -c \\ to clear previous logs
logcat -v time>yourLogs.txt & \\ to capture fresh logs
When I destroy an object made of several bodies connected by joints, my application crashes without an error. Of course I did some research and found that this happens when one destroys bodies while the physics engine calculates a step. So I just add the bodies to a list and destroy them in onUpdate(), but that didn't help. The funny thing is that destroying simple bodies works like a charm even outside onUpdate() and never ever caused a crash.
There was no error output, just once I managed to catch one saying that the problem is a NullPointerException in World.java on line 507. Surprisingly, there I found the following:
public boolean isLocked()
{
return jniIsLocked( addr );
}
Could someone tell me what could be going on? I even went so far as to destroy the bodies one at a time:
if (!destroyList.isEmpty()){
Body b = destroyList.get(0);
destroyList.remove(0);
mPhysicsWorld.destroyBody(b);
}
The problem persists though.
Notes: The object I am destroying is made of several bodies connected by WeldJoints to one central body. The bodies overlap, so I use negative groupIndex to prevent them from colliding with each other. Removing all the joints associated with a particular body before removing it does not help.
Error output:
05-31 15:32:02.486: W/dalvikvm(927): JNI WARNING: JNI method called with exception raised
05-31 15:32:02.497: W/dalvikvm(927): in Lcom/badlogic/gdx/physics/box2d/World;.jniStep (JFII)V (CallBooleanMethodV)
05-31 15:32:02.497: W/dalvikvm(927): Pending exception is:
05-31 15:32:02.506: I/dalvikvm(927): Ljava/lang/NullPointerException;:
05-31 15:32:02.526: I/dalvikvm(927): at com.badlogic.gdx.physics.box2d.World.contactFilter(World.java:507)
05-31 15:32:02.526: I/dalvikvm(927): at com.badlogic.gdx.physics.box2d.World.jniStep(Native Method)
05-31 15:32:02.536: I/dalvikvm(927): at com.badlogic.gdx.physics.box2d.World.step(World.java:298)
...
I think you have to first remove the physics connector also and you have to do all this thing into the update method.
So, the remove sequence is
1. Remove joints from the body
2. Remove physics connector
3. Destroy body from the world
and other necessary thing you have to manage manually that I was not mentioned.
EDIT : I found another thing for you. You have to implement runnable handler to destroy body and joints. The following code work for me where I saw how to delete body.
dRunnableHandler.postRunnable(new Runnable() {
#Override
public void run() {
// destroy the bullet body
PhysicsConnector physicsConnector = gameObject
.getPhysicsWorld().getPhysicsConnectorManager()
.findPhysicsConnectorByShape(Bullet.this);
gameObject.getPhysicsWorld().unregisterPhysicsConnector(
physicsConnector);
gameObject.getPhysicsWorld().destroyBody(bulletBody);
particleSystem.setParticlesSpawnEnabled(false);
gameObject.getEngine().getScene().detachChild(Bullet.this);
gameObject.removeBulletCounter++;
}
});
It´s just an idea, but maybe yo should destroy joints before destroying bodies.
Whether I use this:
process = Runtime.getRuntime().exec("logcat -d time");
or that:
process = new ProcessBuilder()
.command("logcat", "-d", "time")
.redirectErrorStream(true)
.start();
I get the same results: it often hangs within the exec() or start() call, no matter what I tried to do!
The thread running this cannot even be interrupted with Thread.interrupt()! The child process is definitely started and if killed the above commands return.
These calls may fail on first attempt, so THERE IS NO WAY TO READ THEIR OUTPUT! I can also use a simple "su -c kill xxx" command line, same result!
EDIT: Started debugging the java_lang_ProcessManager.cpp file in an NDK project with some debugging logs! So here is what I found so far, after the fork() the parent does this:
int result;
int count = read(statusIn, &result, sizeof(int)); <- hangs there
close(statusIn);
Though the child process is not supposed to block on it: That's what the child does (if started at all!):
// Make statusOut automatically close if execvp() succeeds.
fcntl(statusOut, F_SETFD, FD_CLOEXEC); <- make the parent will not block
// Close remaining unwanted open fds.
closeNonStandardFds(statusOut, androidSystemPropertiesFd); <- hangs here sometimes
...
execvp(commands[0], commands);
// If we got here, execvp() failed or the working dir was invalid.
execFailed:
int error = errno;
write(statusOut, &error, sizeof(int));
close(statusOut);
exit(error);
The child can fail for 2 reproducible reasons:
1- child code is not running, but the parent believes it is!
2- child blocks on
closeNonStandardFds(statusOut, androidSystemPropertiesFd);
In either case the read(statusIn...) in the parent ends in deadlock! and a child process is left dead (and cannot be accessed, pid unknown, no Process object)!
This problem is fixed in Jelly Bean (Android 4.1) but not in ICS (4.0.4) and I guess it will never be fixed in ICS.
Above solution didn't prove to be reliable in any ways, causing more issues on some devices!
So I reverted back to the standard .exec() and kept digging...
Looking at the child code that hangs, I noticed the child process will hang while trying to close all file descriptors inherited from the parent (except the one created within the exec() call) !
So I search the whole app code for any BufferedReader/Writer and similar classes to make sure those would be closed when calling exec()!
The frequency of the issue was considerably reduced, and actually never occured again when I removed the last opened file descriptor before calling exec().
NB: Make sure SU binary is up-to-date, it can actually cause this issue too!
Enjoy your search ;)
Bug fix in Bionic was commited monthes ago, but it still hasn't been included in Android 4.0.4.
I have the same problem on ICS (seem to works fine on Android < 4). Did you find a solution?
A simple workaround could be to call the "exec" method in a dedicated thread with a timeout-join so that this situation could be "detected" (yes I know it's not very elegant...)