43

Every so often my app will crash and my log will read:

@@@ ABORTING: INVALID HEAP ADDRESS IN dlfree
Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1)

Sometimes code=2, but always Fatal signal 11 and invalid heap address.

I've tried researching what this means and how to fix it. This thread has been the most helpful; however, I'm still without a solution.

The error occurs when I run a couple of AsyncTasks to download several images.

This is my main AsyncTask

public class FetchArtistImages extends AsyncTask<Void, Integer, String[]> implements Constants {

private final WeakReference<Context> contextReference;

public FetchArtistImages(Context context) {
    contextReference = new WeakReference<Context>(context);
}

@Override
protected String[] doInBackground(Void... params) {
    String[] projection = new String[] {
            Audio.Artists._ID, Audio.Artists.ARTIST
    };
    String sortOrder = Audio.Artists.DEFAULT_SORT_ORDER;
    Uri uri = Audio.Artists.EXTERNAL_CONTENT_URI;
    Cursor c = contextReference.get().getContentResolver()
            .query(uri, projection, null, null, sortOrder);
    ArrayList<String> artistIds = new ArrayList<String>();
    if (c != null) {
        int count = c.getCount();
        if (count > 0) {
            final int ARTIST_IDX = c.getColumnIndex(Audio.Artists.ARTIST);
            for (int i = 0; i < count; i++) {
                c.moveToPosition(i);
                artistIds.add(c.getString(ARTIST_IDX));
            }
        }
        c.close();
        c = null;
    }
    return artistIds.toArray(new String[artistIds.size()]);
}

@Override
protected void onPostExecute(String[] result) {
    for (int i = 0; i < result.length; i++) {
            new LastfmGetArtistImages(contextReference.get()).executeOnExecutor(
                    AsyncTask.THREAD_POOL_EXECUTOR, result[i]);
    }
    super.onPostExecute(result);
}

Even though I've tried researching what's up with this, I still find myself lost when it comes to fixing it. If anyone has some insight, I'd definitely appreciate seeing it. The error isn't thrown every time I execute my AsyncTasks, but I can't find much of a pattern to help isolate why this is occurring. There are a couple of other threads on SO about fatal signal 11, but they don't provide much help in my case.

trincot
  • 317,000
  • 35
  • 244
  • 286
adneal
  • 30,484
  • 10
  • 122
  • 151

2 Answers2

44

I just ran into the same issue and had it at a re-producable state. This is the error I was getting:

08-04 17:37:05.491: A/libc(4233): @@@ ABORTING: INVALID HEAP ADDRESS IN dlfree 08-04 17:37:05.491: A/libc(4233): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1)

What it boiled down to is a function call being made from two different threads at the same time.

More specifically, this function was BluetoothSocket's close() method.

I checked the source code at this website , and the call is not synchronized (not sure if this changed since it is from Android 2.1).

At any rate, do you maybe have a similar scenario where a function call is made from multiple threads? Can't say for sure from the source code you're showing.

Also have you tried not using THREAD_POOL_EXECUTOR? According to the android dev guide:

When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.

Ivan
  • 2,632
  • 1
  • 24
  • 12
  • how did you find out that the method causing your problems was BluetoothSocket's close() method? – bonifaz Oct 04 '12 at 16:02
  • I examined the code and noticed that I was calling the close() method from two different threads probably almost at the same time. – Ivan Oct 06 '12 at 15:03
  • This answer is absolutely correct. I had the same error code (@@@ ABORTING: LIBC: ARGUMENT IS INVALID HEAP ADDRESS IN dlfree addr). In my particular case I had two different threads call a PathMeasure.getPosTan method. After I changed my code to ensure that this would only be called by one thread at a time, the error went away. – Luis Mar 14 '13 at 14:50
  • 1
    Wow, it's true, I'm also using `bluetooth.close()` hehe. Problem solved in seconds! – Salvatorelab May 20 '13 at 12:03
  • It seems that they've changed the implementation of `BluetoothSocket.close` in [4.2](http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.2_r1/android/bluetooth/BluetoothSocket.java#BluetoothSocket.close%28%29). – snak Jul 09 '13 at 08:50
  • It may help others, but my issue was I was calling `Canvas.drawLine()` (on completely different canvas' / bitmaps) in separate threads. And in rare instances, the method (using internal C code for drawing?) would be accessed at the exact same time and crash. – IAmGroot Apr 01 '16 at 11:00
  • I can solve my issue using this but one other problem is occurring. My view goes to hang when I use THREAD_POOL_EXECUTOR or synchronized method. what I have to do now? any idea, please... – Priyanka Aug 08 '19 at 06:08
8

I had this same error yesterday. It always happened but not always consistently. What caused it for me has so far not been mentioned.

I thought I might have a similar issue because I too was dealing with threads, however I removed all my threading and the problem was still occurring. Finally after a bunch of print statements I was able to track it down to a class I had instanced which had a pointer as a private member, but I forgot to initialize the pointer.

Later when that class destructed it was trying to delete the pointer, however because the pointer was not initialized to NULL, it may or may not have some garbage value, so sometimes it would not cause a crash and other times it would. It is probably because when the garbage value was a memory location that doesn't belong to me or when it does and I delete something important, it causes the crash/error.

Here's a stripped down example of the problem I encountered:

class BadFoo
{
public:
    BadFoo() {} // BAD! We didn't initialize the pointer
    ~BadFoo() {
        if (myPtr) {
            delete myPtr;
        }
    }
    // OTHER MEMBER FUNCTIONS HERE

private:
    int* myPtr;
}

class GoodFoo
{
public:
    GoodFoo() : myPtr(NULL) {} // GOOD! Can't be garbage value now
    ~GoodFoo() {
        if (myPtr) {
            delete myPtr;
        }
    }
    // OTHER MEMBER FUNCTIONS HERE

private:
    int* myPtr;
}

Interesting to note, this crash did not occur on my Transformer Prime, but did on my Nexus4. Just goes to show we should test on multiple devices! So far the Nexus wins on helping me track down bugs as it seems to be a lot pickier.

PolyMesh
  • 2,228
  • 2
  • 20
  • 23
  • Why the downvote? I fail to see why making sure pointers are initialized is a bad thing, especially when it also causes the error in question. – PolyMesh Jul 19 '13 at 23:24