Android Fatal signal 6 (SIGABRT) from asyncTask - android

I have a working android game which occasionally force closes on slow devices with the error
Fatal signal 6 (SIGABRT), code -6 in tid 14620 (AsyncTask #1)
Research indicated to me that this was due to delaying the execution of the UI thread, so, i bundled up the peace of code (about 200 lines of bitmap and region creation) into an AsyncTask (doInBackground method) and i now run that task from the UI thread using task.execute.
The problem is, this has in no way stopped the error. If anything the app force closes more frequently during the execution of that code despite the fact it should be running in an asyncTask.
In the interest of being thorough, the error is triggered during the execution of this part of the code (extract from the 200ish block):
Back.outerPath.setFillType(Path.FillType.EVEN_ODD);
Region tempRegion = new Region(PathBoundsRectangle);
Back.outerRegion.setPath(Back.outerPath, tempRegion);
Back.innerRegion.setPath(Back.innerPath, tempRegion);
Back.fastRegion.setPath(Back.speedPath, tempRegion);
Back.slowRegion.setPath(Back.slowPath, tempRegion);
Back.outerRegion.op(Back.innerRegion, Region.Op.XOR);
Matrix scaleMatrix = new Matrix();
RectF rectF = new RectF();
Back.innerPath.computeBounds(rectF, true);
scaleMatrix.setScale(1.1f, 1.1f,rectF.centerX(),rectF.centerY());
Back.innerPath.transform(scaleMatrix);
Back.outerPath.computeBounds(rectF, true);
scaleMatrix.setScale(0.9f, 0.9f,rectF.centerX(),rectF.centerY());
Back.outerPath.transform(scaleMatrix);
Back.outerSideBandRegion.setPath(Back.outerPath, tempRegion);
Back.outerSideBandRegion.op(Back.outerRegion, Region.Op.XOR);
Back.innerSideBandRegion.setPath(Back.innerPath, tempRegion);
Back.innerSideBandRegion.op(Back.innerRegion, Region.Op.XOR);
Any ideas? Is it possible the code is still running on the UI thread? Can this error be due to something else?
EDIT: It turns out the error is coming from the Region.op.XOR manipulations. Anyone see how this could cause a Fatal Error?

I have also observed this when calling Region.Op.INTERSECT on regions derived from extremely long and complex paths.
The solution that works for me is to maintain a record of all the path waypoints, and then to build a list of smaller paths onto which the Region.Op.INTERSECT operation gets executed individually.

Related

Fatal signal 11 (SIGSEGV), code 2, fault addr 0x9a44a2e8 in tid 19935 (GLThread 3723)

Im using libgdx to make an android game. The game was working fine but then after after adding this line the app started to randomly close.
game.debugRenderer.render(game.world,playerCamera.combined);
The game does have bodies that are being destroyed in the render loop but its at the end of the loop . All that the logcat is showing is
A/libc: Fatal signal 11 (SIGSEGV), code 2, fault addr 0x9a44a2e8 in tid 19935 (GLThread 3723)
[ 07-23 18:09:09.086 299: 299 W/ ]
debuggerd: handling request: pid=19890 uid=10268 gid=10268 tid=19935
Application terminated.
I dont know where to start debugging. The app crashes at random interval, frequently(not always) when the player body is destroyed. Sometimes the ground tile just moves at random and then the app crashes. I dont know what the error is and where to start from. If required i'll post the github link.
Any help would be highly appreciated.
Make sure you're not deleting physics body when physics world is in the middle of a time step. You aren't allowed to destroy anything while Box2D is doing the simulation step.
if(!world.isLocked()){
// delete body
}
So the problem was with the texture I was importing. All of the coding was fine. Replacing the image with another file seemed to solve the issue.

TransitionDrawable causing ANR in android

im having an issue with TransitionDrawable class in android causing an ANR in strict mode. Here is the method call causing the ANR:
private void crossFadeImages(Drawable imageToFadeOut, Drawable imageToFadeIn) {
TransitionDrawable td = new TransitionDrawable( new Drawable[] {
imageToFadeOut,
imageToFadeIn
});
m_myimageView.setImageDrawable(td);
td.startTransition(200);
}
i am passing two drawables. the imageToFadeOut has the following specs:
337X599 PNG (32-bit color) 93.85KB
and the imageToFadeIn has the following specs:
337X599 PNG (32-bit color) 395.16KB
and the ANR is being caused in a nexus 5 emulator api 19 xxhdpi. The actual ANR shows up in strict mode mostly.
i get the following log error
"I/Choreographer: Skipped 33 frames! The application may be doing too much work on its main thread."
the method is called from the main thread. How can i resolve this ? Or is there another way to do the cross fading between two images ?

Switching from Main thread to multiple Thread while analyzing a frame

I have been working on a Mobile application that analyzes the frame looking for specific objects. The processing was to heavy, and I keep getting
05-08 17:44:24.909: I/Choreographer(31606): Skipped 114 frames! The application may be doing too much work on its main thread.
So i switched the image processing to threads, now it is much faster but I am not able to recognize any object . The data(the different frames) is not updating and I don't know why. Here is what I'm doing in pseudocode( SurfaceHolder.Callback ,Camera.PreviewCallback and camera.addCallbackBuffer(data) are implemented )
public void onPreviewFrame(byte[] data, Camera camera)
{
Imageprocessor np = new ImageProcessor(data);
np.start()
results = np.getResults();
}
From the debugging I have done so far I know that start is analyzing the whole frame, but . the data is not updating it keeps stacked at the very first frame. This does not happen if I do it in the main Thread like this,
public void onPreviewFrame(byte[] data, Camera camera)
{
Imageprocessor np = new ImageProcessor();
np.process(data)
results = np.getResults();
}
This works but it force me to skip many frames. The answer may be easy, but I could not find it online.
Forgive me if I am posting a very noob question
Thanks in advance
That's because in the single threaded case, the np.process() is complete before you execute results=..., but in the threaded case, the results=... follows immediately after starting the threads. Unless getResults() waits for all the threads to finish??

Android heap corruption on USB receive

I'm trying to write a service that communicates with a USB device using USB Interrupt transfer. Basically I'm blocking on UsbConnection.requestWait() in a thread to wait for interrupts transfers in, then pass those to the activity using an intent.
I seem to be having problems when the USB devices sends me a largish number of interrupt packets in a row (about 50). It sometimes works but usually the app crash with a message of that flavor:
02-23 01:55:53.387: A/libc(8460): ### ABORTING: heap corruption detected by tmalloc_small
02-23 01:55:53.387: A/libc(8460): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 8460 (pf.mustangtamer)
it's not always a malloc call that fails, I have seen several flavors of malloc (dlmalloc, malloc_small) as well as dlfree. In every instance I get a Fatal Signal 11 and a reference to 0xdeadbaad so somehow I am corrupting the heap.
It's not obvious from the heap dump what is causing the corruption.
Here is what I believe is the offending code (the problem only occurs when receiving many packets back to back to back):
private class ReceiverThread extends Thread {
public ReceiverThread(String string) {
super(string);
}
public void run() {
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
buffer.clear();
UsbRequest inRequest = new UsbRequest();
inRequest.initialize(mUsbConnection, mUsbEndpointIn);
while(mUsbDevice != null ) {
if (inRequest.queue(buffer, BUFFER_SIZE) == true) {
// (mUsbConnection.requestWait() is blocking
if (mUsbConnection.requestWait() == inRequest){
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
//TODO: use explicit intent, not broadcast
Intent intent = new Intent(RECEIVED_INTENT);
intent.putExtra(DATA_EXTRA, bytes);
sendBroadcast(intent);
} else{
Log.d(TAG, "mConnection.requestWait() returned for a different request (likely a send operation)");
}
} else {
Log.e(TAG, "failed to queue USB request");
}
buffer.clear();
}
Log.d(TAG, "RX thread terminating.");
}
}
Right now the activity is not consuming the intents, I'm trying to get the USB communication to stop crashing before I implement that side.
I'm not seeing how the code above can corrupt the heap, possibly through some non-thread safe behavior. Only one request is queued at a time so I think "buffer" is safe.
My target is a tablet running JB 4.3.1 if that makes a difference.
I'm not seeing anything wrong with this either. You may want to try removing code from your loop and see if it still corrupts the heap to help you zoom on the offending area.
Remember that heap operations are usually delayed, the garbage collector doesn't run immediately, so you could be corrupting it somewhere else, and it's only showing up in this loop because it is very heap intensive.
try to use a larger heap size by setting android:largeHeap="true" in your application manifest.
I would have asked these questions in a comment, but alas, not enough rep.
I see nothing directly wrong with the code above, but I would check the following:
What is BUFFER_SIZE? crazily, I've had very strange problems with UsbRequest.queue() for sizes greater than 15KB. I'm pretty sure that this wouldn't cause your heap corruption, but it could lead to weirdness later. I had to break my requests into multiple calls to queue() to do large reads.
Are you using a bulk USB endpoint? I don't know what your application is, so I cant say for sure if you should be using a bulk endpoint or not, but its the type of endpoint intended for large transfers.
Lastly, when I encountered this 0xdeadbaad problem (detected by tmalloc_large), it had nothing to do with the code I thought was at fault (the code near the malloc) - it was of course a threading issue in which I had JNI native code reading/writing the same buffers on multiple separate threads! Its only that it gets detected when malloc is called, as user3343927 mentioned.

Catch C++ signal in Android NDK and still print crash dump

I'm catching C++ signals so I print some debugging information. But doing so I am unable to get the crash dump that the NDK prints when you crash.
Can you manually print the crash dump. I see debuggerd.c (http://kobablog.wordpress.com/2011/05/12/debuggerd-of-android/) does the work but not sure how I would use it. Otherwise is there some way to rethrow the signal without my signal handler catching it and get the crash dump still.
Here is what I currently do:
struct sigaction psa, oldPsa;
void CESignalHandler::init() {
CELogI("Crash handler started");
psa.sa_sigaction = handleCrash;
psa.sa_flags = SA_SIGINFO;
//sigaction(SIGBUS, &psa, &oldPsa);
sigaction(SIGSEGV, &psa, &oldPsa);
//sigaction(SIGSYS, &psa, &oldPsa);
//sigaction(SIGFPE, &psa, &oldPsa);
//sigaction(SIGILL, &psa, &oldPsa);
//sigaction(SIGHUP, &psa, &oldPsa);
}
void CESignalHandler::handleCrash(int signalNumber, siginfo_t *sigInfo, void *context) {
static volatile sig_atomic_t fatal_error_in_progress = 0;
if (fatal_error_in_progress) //Stop a signal loop.
_exit(1);
fatal_error_in_progress = 1;
char* j;
asprintf(&j, "Crash Signal: %d, crashed on: %x, UID: %ld\n", signalNumber, (long) sigInfo->si_addr, (long) sigInfo->si_uid); //%x prints out the faulty memory address in hex
CELogE(j);
CESignalHandler::getStackTrace();
sigaction(signalNumber, &oldPsa, NULL);
}
You need to reset the signal handler(s) to the previous function, and then crash again -- ideally at the point where the signal was originally thrown. You can do this by passing a struct sigaction in as the 3rd argument to sigaction(), and using the saved value to restore the original behavior in the signal handler.
This can be a bit tricky because of the way debuggerd works (and because the way it works has changed over time). For a "hard" failure like a segmentation fault, returning from the signal handler just causes the same signal to be re-thrown. The Android crash handler uses this to its advantage by contacting debuggerd, waiting for it to attach with ptrace, and then resuming. debuggerd then gets to watch the process as it crashes (for the second time).
This doesn't work for "soft" failures, e.g. somebody manually sends your process a SIGABRT or gets a SIGPIPE from a write(). If the signal handler contacts debuggerd and resumes, the process just clears the signal and continues on, leaving debuggerd to wait indefinitely for a second crash that never happens. This was partially fixed a couple of releases back; now the debug code re-issues the signal itself (which doesn't actually do anything until the signal handler returns, because the signal is blocked while the handler runs). This usually works, and when it doesn't, debuggerd will time out and drop the connection.
So. If you receive a segmentation fault or bus error, you can just restore the original signal handler and then return from yours, and when the process crashes again the debuggerd handler will deal with it. If somebody sent you a SIGHUP, you should handle it entirely yourself, because debuggerd doesn't care about that signal at all.
Things get weird with SIGFPE. This is a "soft" failure, because most ARM CPUs don't have a hardware integer divide instruction, and the signal is actually being sent explicitly from the libgcc __div0 function. You can restore the signal handler, and then re-send the signal yourself; but depending on what version of Android you're running you might have to send it twice. Ideally you'd like to be doing this from the code that encountered the arithmetic problem, rather than the signal handler, but that's tricky unless you can replace __div0. You would need to send the signal with tgkill(), not kill(), as the latter will result in the signal being sent to the main thread of the process, which would cause debuggerd to dump the stack for the wrong thread.
You might be tempted to copy the handler out of bionic/linker/debugger.cpp, but that's a bad idea -- the protocol used to communicate between bionic and debuggerd has changed in the past and will likely change again.
You need call oldPsa manually like this
oldPsa(signalNumber, sigInfo, context)

Categories

Resources