How to crash an Android app programmatically? - java

I want to test out crash report using acra but the first step is I need to simulate a fatal crash in Android using code.
Any idea?

Just execute this code: divide by zero
Update: Also can try this
Create a method,
public void stackOverflow() {
this.stackOverflow();
}
And call this somewhere/buttonClick
OR simply throw an uncaught exception
throw new RuntimeException("This is a crash");
Bingo!

Access a view that is not defined.
Access the first element of an empty list without checking.
Divide by Zero.
Throw the device out the window.
Submerge the device in water.

Don't declare activity in the Android Manifest .

You could try a Null Pointer exception.
Integer i = null;
Then invoke any method on the object.
i.byteValue();
Invoking a method on an object that hasn't been initialized will crash the app.

A very simple approach... and is very important to understand that why it happened.
Try initiating a variable in onCreate() before the setContentView() method, then use it to call a method or variable or try registering it to some listener..
Eg:
Button b;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
b = (Button)findViewById(R.id.butt);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
}
});
setContentView(R.layout.main);
}
This crashed, because before setContentView() none of the components/view in the main.xml layout got their ids.

Simply create in your main.xml a button like this:
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="crash"
android:text="Crash me" />
then run your app and click for crash

Most simple I know : throw null.
You can't throw null, so a NullPointerException is raised.
throw null;

you can crash with a simple null point exception.
throw new NullPointerException();

in addition to #vinnet-shukla answer:
"OR simply throw an uncaught exception"
throwing uncaught exception to do a crash is bad idea as the exception could by caught somwhere higher in the stack - especially when whe don't know where we are right now :)
more ellegant way is to use ERROR
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.
so we could make our own Error subclass and use it:
/*
* usage:
*
* CrashError.doCrash();
*
*/
public class CrashError extends Error {
public CrashError() {
this("simulated crash");
}
public CrashError(String msg) {
super(msg);
}
public static void doCrash() {
throw new CrashError();
}
}
but if we talk about other possibilities we could also a throw checked exception :)
this will also be a lesson how we could RETHROW CHECKED EXCEPTION :) with other way than use of sun.misc.Unsafe especially when the class is not available in VM implementation
#SuppressWarnings("unchecked")
public static <E extends Throwable> void throwAnyT(Throwable e) throws E {
throw (E) e;
}
public static void throwUnchecked(Throwable e) {
throwAny(e);
// should never get there.
throw new InternalError();
}
public static void crash() {
throwUnchecked(new java.io.IOException("simulated crash"));
}
in addition to #audric answer:
"You can't throw null"
yes you can :) it's exactly what you are doing in your example and yes it could get undetectable if the catch block will not use Throwable - the NPX will never be thrown and simply there will be normal flow when code will still execute and yes i'll have seen this and experienced by myself :) on ANDROID DALVIK
and what about..? maybe it could fulfill your needs?
java specific (also in android):
- Runtime.getRuntime().exit(int);
- System.exit(int);
- Runtime.getRuntime().halt(int);
android specific:
- android.os.Process.killProcess(int);
- android.os.Process.killProcessQuiet(int);
- android.os.Process.sendSignal(int,int);
- android.system.Os.kill(int);

For kotlin:
val test = ("0")
println(test[1])

Force crash after some delay like this,
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
Log.i("tag", "This'll run 10 seconds later");
throw new RuntimeException("This is a crash");
}
},
10000);
Ref-1 & Ref-2

If you are using firebase crashlytics, then there is a very easy way to do this. Mentioned in their document also.
val crashlytics = FirebaseCrashlytics.getInstance()
crashlytics.log("my message")

You can crash the application simply with this line of code.
throw new RuntimeException("Test Crash"); // Force a crash
You can pass the message, in this case "Test Crash", which can be useful later to refer.
One step ahead,
Make sure none of your application's class files implement UncaughtExceptionHandler interface as below,
public class MyApplication extends Application implements Thread.UncaughtExceptionHandler{
Otherwise the above exception or any exception for that matter, would be caught/consumed by that class, resulting in not crashing the app. However, you can get hold of that exception in uncaughtException(Thread t, Throwable e) method as below and take the required action. In your case, you'd be reporting it to the Acra using their supported SDK methods.
#Override
public void uncaughtException(Thread t, Throwable e) {
Log.e("MyApplication", "Error", e);
}

You can use activity manager to crash the app with no code changes
adb shell am crash <packagename>

Use the following code:
String xyz=null;
system.out.println(xyz);

Related

Why context.startActivity(intent) not starting the activity and how to handle exception in android?

I have an exception handler which handles exception from an Activity class, the exception handler looks like this.
public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
public static final String TAG = "Exception handler";
private final Context activity;
public ExceptionHandler(Context activity) {
this.activity = activity;
}
#Override
public void uncaughtException(#NonNull Thread thread, #NonNull Throwable throwable) {
Intent error = new Intent(activity, ErrorCatcher.class);
activity.startActivity(error);
}
}
it is initialized from the activity class
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.e(TAG, "onRestart: Hey just created");
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this.getApplicationContext()));
// other methods and function
}
when the control comes to the exception handler, the activity is not created, instead of a blank page that hangs my app.
The only message I get is
I/Timeline: Timeline: Activity_launch_request time:417281208 intent:Intent { cmp=com.yyy.xxx/com.yyy.xxx.Activities.Error }
EDIT: Ok, after some digging I find, if no exception is thrown then the activity is started (i.e I can see the Activity page) but when an exception is thrown that's when a blank page is displayed. Why is this the condition for only when an exception is thrown and what is a better way to handle exception in android?? any help?
EDIT 2 : it's similar to this https://codecrunch.co/blog/custom-error-handling-in-android/
before the startActivity, add error.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);. There are also more complete answers here
This code may be helpful for you
Application application = (Application) context.getApplicationContext();
Intent intent = new Intent(application, ErrorActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
application.startActivity(intent);
If not then notify me, I will send you complete code for exception handling!
It worked for when i used try/catch instead of
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this.getApplicationContext()));
to handle exception's , it might not be the best approch but it's worth a try.
First off, you are using an Application Context to try and start an activity. This may be causing some of your problems. This can be done, but I think there is a simpler way for all this to play out.
It should also be noted that you forgot the rest of the code inside the
#Override
public void uncaughtException
....
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(10);
Why is this the condition for only when an exception is thrown...
It's because you have overridden the uncaughtException method. So when you get an uncaught exception, you are going to start the Error.class Activity.
#Override
public void uncaughtException(#NonNull Thread thread, #NonNull Throwable throwable) {
Intent error = new Intent(activity, ErrorCatcher.class);
activity.startActivity(error);
}
...and what is a better way to handle exception in android??
There are a number of ways that you can handle an exception. It really depends on what the use case is. In general, you should be handling errors as they occur, at least in the beginning. You can either do this with a try/catch block on methods that can throw errors; or, you can "bubble up the error" to handle it in an appropriate place, depending on your app's architecture, by creating methods that throw errors. Without more detail, I'm not able to provide an accurate response as to the best way to handle errors. In my app's, I'll typically throw a toast, if it requires user notification, or another path if there is something like a network failure.
Exception handling is a complex issue and should be handled as such. There is no single right answer for how to handle errors. However, some basics are:
Handle all exceptions. If you have a method that throws an error, make sure you wrap in a try/catch and handle appropriately. This should prevent any "uncaught exceptions".
Be specific in the errors you are handling. It appears like you are trying to create a "catch-all" for any uncaught errors in your activity. I would not go about it that way. I would wrap all the code in a try/catch and handle the errors as they come up. As I think about your code, I'm guessing that the reason you get a blank screen is that you haven't created a layout for your error class, but I could be wrong.
TLDR; If I were you I'd get rid of the:
#Override
public void uncaughtException(#NonNull Thread thread, #NonNull Throwable throwable) {
Intent error = new Intent(activity, ErrorCatcher.class);
activity.startActivity(error);
}
Also get rid of this:
protected void onCreate(Bundle savedInstanceState) {
Log.e(TAG, "onRestart: Hey just created");
//Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this.getApplicationContext()));
From there I would figure out what methods are throwing errors and handle them when you call them. That is going to be the simplest method. From there you can consider a larger and more complex approach to error handling. You don't necessarily need to create a new activity for an error. If you want to, I'd do it in the finally block. Make sure you have created a layout for the error activity; otherwise, it will just be blank; added the error activity to the manifest (or it will crash).
try{
//your add all your method calls here.
} catch (Exception E){
//handle generic exception
} catch (ThreadException e){
//handle the thread exception
...add more catches for more specific errors
} finally{
//Optional call once all exceptions have been caught
Intent error = new Intent(this, ErrorCatcher.class);
startActivity(error);
}
on your overrided uncaughtException method you better start the activity using this code
startActivity(activity,Error.class);

GWT - Unable to catch StatusCodeException with UncaughtExceptionHandler

When Tomcat session times out, I want to redirect my user to the homepage of my GWT app, so that they can login again. To force this, I'm trying to use the StatusCodeException thrown by GWT when the user tries to perform any operation after their session times out -
SEVERE: com.google.gwt.user.client.rpc.StatusCodeException: 0
To achieve this, I'm using the following code -
public void onModuleLoad() {
GWT.UncaughtExceptionHandler uncaughtExceptionHandler = new GWT.UncaughtExceptionHandler() {
public void onUncaughtException(Throwable e) {
if (e instanceof StatusCodeException) {
logger.log(Level.ERROR, "Exception caught!");
logger.log(Level.ERROR, ((StatusCodeException) e).getStatusCode());
}
}
};
GWT.setUncaughtExceptionHandler(uncaughtExceptionHandler);
try {
// rest of the code in onModule() - I'm expecting any operation to throw StatusCodeException when session times out.
} catch (RuntimeException ex) {
uncaughtExceptionHandler.onUncaughtException(ex);
}
}
This is not working. Instead of getting caught by the code, the StatusCodeException is being displayed on the console. What am I doing wrong here?
The idea is to catch StatusCodeException and use its getStatusCode() method to find out if the HTTP error code is 403. If it is, I want to use Window.Location.assign("https://example.com/redirect"); to redirect them to a login page.
onFailure(Throwable caught) {
logger.error(caught);
}
Your AsyncCallback.onFailure is doing exactly what you asked it to do - it is logging the error, but not throwing it. Since it wasn't thrown, the uncaught exception handler doesn't handle it (it can't be not-caught, if it wasn't thrown... if that makes sense).
One option could be that you could populate the method with throw caught, but java won't like this. Instead, the easiest answer to your specific on is simply to pass it to the handler:
onFailure(Throwable caught) {
GWT.getUncaughtExceptionHandler().onUncaughtException(ex);
}
One other option you have: since no AsyncCallback will ever throw this, putting the StatusCodeException in the UncaughtExceptionHandler seems a bit odd. Instead, consider making your own AsyncCallback base class, something like this:
public abstract class NetworkAsyncCallback<T> implements AsyncCallback<T> {
#Override
public void onFailure(Throwable t) {
if (e instanceof StatusCodeException) {
logger.log(Level.ERROR, "Exception caught!");
logger.log(Level.ERROR, ((StatusCodeException) e).getStatusCode());
}
}
}
Now, when you make a call, you just have to pass in a new NetworkAsyncCallback<T> and only implement onSuccess. You can skip onFailure if all it was going to do was pass the exceptions to the uncaught handler. Or, if you have some other logic, you can override onFailure, handle the appropriate exceptions, and call super.onFailure(caught) with any other errors so that the superclass handles it.
myServer.getSomeData(param, new NetworkAsyncCallback<Result>() {
#Override
public void onSuccess(Result result) {
//...
}
// Skip onFailure, or if you need custom logic, implement it,
// and call super only if the exception isn't part of that logic
});

How to identify a throwable with specific data

I have this caught that catches any uncaught exception
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
}
});
Inside the method, I want to deal with following exception differently than other exceptions:
Caused by: java.lang.NullPointerException
at com.company.si.stats.Statistics.hashString(Statistics.java:192)
at com.company.si.stats.Statistics.sendStatistics(Statistics.java:127)
I want basically to check that it is nullpointer exception coming from com.company.si.stats.Statistics.hashString
How can I do that? I am not sure what parameters in throwable I should compare against?
The code where exception is thrown was not written by me, so I cannot change anything about it.
Important NOTE
I know the way I am approaching this problem is not the right way. But I dont have access to the library raising the exception and I needed a workaround till the bug is fixed in the library. The answer was chosen because it satisfies what I need to, and not what generally should be dne
Disclaimer
This was suggested in the comments and I thought it will be a good idea to add it as an answer, but remember that this is not how you should do it, so please use this answer as an example of how NOT to handle this type of problem. Feel free to also downvote it.
You can check where the exception comes from by looking at its stack trace, or at least at first stack trace element.
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
StackTraceElement[] stackTrace = e.getStackTrace();
if (e instanceof NullPointerException &&
stackTrace != null && stackTrace.length >= 0 &&
"Statistics.java".equals(stackTrace[0].getFileName()) &&
"hashString".equals(stackTrace[0].getMethodName()) &&
192 == stackTrace[0].getLineNumber()) {
// Handle your exception here.
}
}
});
Reasons why you should not do it:
it's really ugly
any change in hashString method will make this useless
because mom said so
any change in Statistics class will make this useless
in case of 2 or 4, finding bugs caused by this exception could be really painful
it's not portable (think about changing the library in the future)
it's bad practice
You can create your own exception, for instance:
public class HashingException extends RuntimeException {
public HashingException(Throwable t) {
super(t);
}
}
As you said, the com.company.si.stats.Statistics.hashString() method wasn't made by you so you can't change it. But you can translate the exception thrown by it. I'm not sure how the method signature looks like, but here's how you can do it:
// ... some code, Statistics object initialization somewhere
String hashString;
try {
hashString = statistics.hashString(someArgumentMaybe);
} catch (Exception e) {
throw new HashingException(e);
}
// result of method is available here as hashString object
and later handle it in your handler class like:
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
if (e instanceof HashingException) {
HashingException hashingException = (HashingException) e;
// Handle your exception here.
Exception cause = e.getCause();
// cause will be NullPointerException
}
}
});
There is a simple way to get your stacktrace as a String or a reader
ByteArrayOutputStream stacktraceContent = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(stacktraceContent));
try (BufferedReader reader =
new BufferedReader(new InputStreamReader(new
ByteArrayInputStream(stacktraceContent.toByteArray())))) {
// Here you can read your stacktrace line by line and match against any
// pattern
}
Also there is a nice Open Source library that filters logs. Its called MgntUtils library. Here you can find an article describing it in detail:
Open Source Java library with stack trace filtering, Silent String parsing Unicode converter and Version comparison. The article also provides links to github (source) and Maven where you can download it or integrate it into your Maven project. Here are the links anyway: MgntUtils on github and Maven link

Throw an Exception without crashing the app

I'm using a crash report library in my Android project. Once activated, it reacts to every uncatched exception and creates a report just before the app shutdown.
So far so good, but I want to add more "control" to this thing and create reports for non-Exceptions too. My idea is to define a "fake" Exception this way:
public final class NonFatalError extends RuntimeException {
private static final long serialVersionUID = -6259026017799110412L;
public NonFatalError(String msg) {
super(msg);
}
}
So, when I want to send a non-fatal error message and create a report, I'll do this:
throw new NonFatalError("Warning! A strange thing happened. I report this to the server but I let you continue the job...");
If called from the main thread, this obviously makes the app crash. So, I tried to throw it on a background thread!
new Thread(new Runnable() {
#Override
public void run() {
throw new NotFatalError("Warning! A strange thing happened. I report this to the server but I let you continue the job...");
}
}).start();
A great idea? No. The app crashes anyway (but the fake crash report is sent as expected). Is there another way to achieve what I want?
Your exception never gets caught, so that's why your application is crashing.
You can do this do catch the exception from your main thread:
Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread th, Throwable ex) {
System.out.println("Uncaught exception: " + ex);
}
};
Thread t = new Thread(new Runnable() {
#Override
public void run() {
throw new NotFatalError("Warning! A strange thing happened. I report this to the server but I let you continue the job...");
}
});
t.setUncaughtExceptionHandler(h);
t.start();
But you can also run the code from your main thread and catch it there.. Like:
try
{
throw new NonFatalError("Warning! blablabla...");
}
catch(NonFatalError e)
{
System.out.println(e.getMessage());
}
Because your exception is extended from the RuntimeException class the default behaviour is to exit the application if the exception is not catched anywhere. So that's why you should catch it before the Java Runtime decides to quit the app.
You are using exception to create logs. You shouldnt do that. If you are using a library like crashlytics (https://try.crashlytics.com/) you can send log reports like in this link: http://support.crashlytics.com/knowledgebase/articles/120066-how-do-i-use-logging
The library you are using should have a similar method.
If you want to continue to use Exceptions, you need to catch them to not crash the application.

Global Exception Handling in an Eclipse RCP app

I want to override the global Exception Handling in my RCP app. Whenever an uncaught Exception happens I want to log it (using java logging) and then exit the app. I have already overwritten the eventLoopException(Throwable exception) method in the ApplicationWorkbenchAdvisor class. But this catches only the event loop exceptions. As of now I have also overwritten the postStartup() method like this:
public void postStartup()
{
Policy.setStatusHandler(new StatusHandler()
{
#Override
public void show(IStatus status, String title)
{
LOGGER.log(Level.SEVERE, "Uncaught Exception", status.getException());
UnexpectedErrorDialog();
PlatformUI.getWorkbench().close();
}
});
}
It logs the exception in my log file and exits the app. But it's obviously not right and the exception is shown twice in the console, cause all I do is intercepting the showing of the exception in a gui dialog to the user. So how can I properly overwrite/change the global exception handling, so that my code (log) is used instead of the default one?
I would suggest you to use org.eclipse.ui.statusHandlers extension point
Thanks to sambi reddy's tip i have now overwritten AbstractStatusHandler in the ApplicationWorkbenchAdvisor class
#Override
public synchronized AbstractStatusHandler getWorkbenchErrorHandler() {
if (myStatusHandler == null) {
myStatusHandler = new MyStatusHandler();
}
return myStatusHandler;
}
MyStatusHandler extends AbstractStatusHandler and i have overwritten the handle method like this:
#Override
public void handle(StatusAdapter statusAdapter, int style)
{
if(statusAdapter.getStatus().matches(IStatus.ERROR) && ((style != StatusManager.NONE)))
{
LOGGER.log(Level.SEVERE, "Uncaught Exception", statusAdapter.getStatus().getException());
UnexpectedErrorDialog();
PlatformUI.getWorkbench().close();
}
}
seems to work right, only downside is that i still get 2 console outputs.

Categories