2012-05-19 9 views
42

Jeder so oft wird meine Anwendung zum Absturz bringen und mein Log erscheint:Ungültige Heap-Adresse und fatales Signal 11

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

Manchmal code=2, aber immer Fatal signal 11 und invalid heap address.

Ich habe versucht zu erforschen, was das bedeutet und wie man es beheben kann. This thread has been the most helpful; aber ich habe immer noch keine Lösung.

Der Fehler tritt auf, wenn ich ein paar AsyncTasks zum Download mehrerer Bilder ausführen.

Das ist mein Haupt 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); 
} 

Auch wenn ich die Nachforschungen habe versucht, was los ist mit diesem, ich mich immer noch verloren finden, wenn es zu Festsetzung kommt. Wenn jemand etwas Einblick hat, würde ich es sehr schätzen, es zu sehen. Der Fehler wird nicht jedes Mal geworfen ich execute mein AsyncTasks, aber ich kann nicht viel von einem Muster zu helfen, zu isolieren, warum dies auftritt. Es gibt ein paar andere Threads über SO über fatal signal 11, aber sie bieten nicht viel Hilfe in meinem Fall.

+0

Gibt es JNI in Ihrer Anwendung? –

+0

Nein, das ist nicht. – adneal

+0

Ich habe JNI in meiner Anwendung und bekomme diesen Fehler. Irgendwelche Vorschläge, @JulieinAustin –

Antwort

43

Ich lief gerade in das gleiche Problem und hatte es in einem re-producable Zustand. Dies ist der Fehler, ich war immer:

08-04 17: 37: 05,491: A/libc (4233): @@@ ABORTING: INVALID ADDRESS IN HEAP dlfree 08-04 17: 37: 05,491: A/libc (4233): Fatal Signal 11 (SIGSEGV) bei 0xdeadbaad (code = 1)

was es kochte ist eine Anruffunktion von zwei verschiedenen Threads zur selben Zeit hergestellt werden.

Genauer gesagt war diese Funktion die Close() - Methode von BluetoothSocket.

Ich überprüfte den Quellcode at this website, und der Anruf wird nicht synchronisiert (nicht sicher, ob dies geändert hat, da es von Android 2.1 ist).

Auf jeden Fall haben Sie vielleicht ein ähnliches Szenario, in dem ein Funktionsaufruf von mehreren Threads gemacht wird? Kann nicht sicher aus dem Quellcode sagen, den Sie zeigen.

Haben Sie auch versucht, THREAD_POOL_EXECUTOR nicht zu verwenden? Nach the android dev guide:

Bei der ersten Einführung wurden AsyncTasks seriell auf einem einzelnen Hintergrund Thread ausgeführt. Beginnend mit DONUT wurde dies in einen Pool von Threads geändert, der es mehreren Tasks ermöglichte, parallel zu arbeiten. Beginnend mit HONEYCOMB werden Tasks in einem einzelnen Thread ausgeführt, um häufige Anwendungsfehler zu vermeiden, die durch die parallele Ausführung verursacht werden.

+0

Wie haben Sie herausgefunden, dass die Methode "close()" von BluetoothSocket die Methode war, die Ihre Probleme verursacht hat? – bonifaz

+0

Ich habe den Code untersucht und festgestellt, dass ich die Methode close() aus zwei verschiedenen Threads wahrscheinlich fast gleichzeitig aufgerufen habe. – Ivan

+0

Diese Antwort ist absolut richtig. Ich hatte den gleichen Fehlercode (@@@ ABORTING: LIBC: ARGUMENT IST INVALID HEAP ADDRESS IN dlree addr). In meinem speziellen Fall habe ich zwei verschiedene Threads eine PathMeasure.getPosTan-Methode aufrufen. Nachdem ich meinen Code geändert hatte, um sicherzustellen, dass dieser immer nur von einem Thread gleichzeitig aufgerufen wurde, ging der Fehler verloren. – Luis

8

Ich hatte gestern denselben Fehler. Es ist immer passiert, aber nicht immer konsequent. Was es für mich verursacht hat, wurde bisher nicht erwähnt.

Ich dachte, ich könnte ein ähnliches Problem haben, weil ich auch mit Threads beschäftigt war, jedoch habe ich alle meine Threading entfernt und das Problem trat immer noch auf. Schließlich konnte ich es nach einer Reihe von Druckanweisungen auf eine Klasse, die ich instanziert hatte, verfolgen, die einen Zeiger als privates Mitglied hatte, aber ich vergaß, den Zeiger zu initialisieren.

Später, als diese Klasse zerstört wurde, versuchte sie, den Zeiger zu löschen, da der Zeiger jedoch nicht auf NULL initialisiert wurde, kann er einen Wert enthalten oder nicht, so dass er manchmal nicht zum Absturz führen würde . Es ist wahrscheinlich, weil, wenn der Müllwert ein Speicherort war, der mir nicht gehört oder wenn es tut, und ich etwas wichtiges lösche, verursacht es den Abbruch/den Fehler.

Hier ist ein abgespeckte Beispiel für das Problem begegnete ich:

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

Interessant zu beachten, dieser Absturz nicht auf meinem Transformer Prime nicht auftritt, aber tat auf meinem Nexus4. Nur um zu zeigen, dass wir auf mehreren Geräten testen sollten! Bis jetzt gewinnt der Nexus, indem er mir hilft, Fehler aufzuspüren, da er viel wählerischer zu sein scheint.

+0

Warum der Downvote? Ich verstehe nicht, warum das Setzen von sicheren Zeigern eine schlechte Sache ist, besonders wenn es auch den fraglichen Fehler verursacht. – PolyMesh

+0

Ihre Antwort löste mein Problem. Vielen Dank – user65721

Verwandte Themen