web-dev-qa-db-fra.com

Adresse de tas non valide et signal fatal 11

De temps en temps, mon application plante et mon journal indique:

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

Parfois code=2, mais toujours Fatal signal 11 et invalid heap address.

J'ai essayé de rechercher ce que cela signifie et comment y remédier. Ce fil a été le plus utile ; cependant, je suis toujours sans solution.

L'erreur se produit lorsque j'exécute quelques AsyncTasks pour télécharger plusieurs images.

Ceci est mon principal 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);
}

Même si j'ai essayé de rechercher ce qui se passe avec ça, je me retrouve toujours perdu quand il s'agit de le réparer. Si quelqu'un a un aperçu, j'apprécierais certainement de le voir. L'erreur n'est pas renvoyée chaque fois que je execute mon AsyncTasks, mais je ne trouve pas beaucoup de modèle pour aider à isoler pourquoi cela se produit. Il y a quelques autres discussions sur SO about fatal signal 11, mais ils ne fournissent pas beaucoup d'aide dans mon cas.

42
adneal

Je suis juste tombé sur le même problème et je l'avais à un état reproductible. Voici l'erreur que j'obtenais:

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

Cela se résumait à un appel de fonction effectué à partir de deux threads différents en même temps.

Plus précisément, cette fonction était la méthode close () de BluetoothSocket.

J'ai vérifié le code source sur ce site , et l'appel n'est pas synchronisé (je ne sais pas si cela a changé car il s'agit de Android 2.1).

En tout cas, avez-vous peut-être un scénario similaire où un appel de fonction est effectué à partir de plusieurs threads? Je ne peux pas dire avec certitude du code source que vous montrez.

Avez-vous également essayé de ne pas utiliser THREAD_POOL_EXECUTOR? Selon le Android :

Lors de leur introduction, les tâches AsyncTasks ont été exécutées en série sur un seul thread d'arrière-plan. À partir de DONUT, cela a été changé en un pool de threads permettant à plusieurs tâches de fonctionner en parallèle. À partir de HONEYCOMB, les tâches sont exécutées sur un seul thread pour éviter les erreurs d'application courantes causées par l'exécution parallèle.

43
Ivan

J'ai eu cette même erreur hier. Cela s'est toujours produit, mais pas toujours. Jusqu'à présent, ce qui l'a causé n'a pas été mentionné.

J'ai pensé que je pourrais avoir un problème similaire parce que moi aussi, je traitais avec des threads, mais j'ai supprimé tous mes threads et le problème persistait. Enfin, après un tas d'instructions imprimées, j'ai pu le retrouver jusqu'à une classe que j'avais instanciée qui avait un pointeur en tant que membre privé, mais j'ai oublié d'initialiser le pointeur.

Plus tard, lorsque cette classe a été détruite, elle essayait de supprimer le pointeur, mais parce que le pointeur n'était pas initialisé à NULL, il peut ou non avoir une valeur de mémoire, donc parfois cela ne provoquerait pas de plantage et d'autres fois. C'est probablement parce que lorsque la valeur de la mémoire était un emplacement mémoire qui ne m'appartient pas ou quand elle le fait et que je supprime quelque chose d'important, cela provoque le crash/erreur.

Voici un exemple dépouillé du problème que j'ai rencontré:

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;
}

Il est intéressant de noter que ce crash ne s'est pas produit sur mon Transformer Prime, mais sur mon Nexus4. Va juste pour montrer que nous devons tester sur plusieurs appareils! Jusqu'à présent, le Nexus gagne à m'aider à traquer les bugs car il semble être beaucoup plus difficile.

8
PolyMesh